Omar
Omar

Reputation: 643

What is 'in' called in this condition (to find it in documentation by its name)

I want to check if some words are in a text file, but I need to make the search case-insensitive, so, I need to know how the "in" inside the if condition works, and see its documentation for an option like that.

But I couldn't find it by searching google, I tried to search using terms like "conditional statements python" but still couldn't find it.

#!/usr/bin/python3

search_words = ['Day 3','day 3']

with open('test-target.txt','r') as targetFile:
    for search_word in search_words:

        if search_word in targetFile.read():
            print('yes')
        else:
            print('no')

        # put the read cursor again at the begining of the file to prepare it fot next read ^o^
        targetFile.seek(0)

the file:

Day 3 Lab ......etc
bla bla bla

the output:

yes
no

Upvotes: 0

Views: 46

Answers (2)

tripleee
tripleee

Reputation: 189507

This is called the "contains" operator, a membership test operator. It doesn't really come with options; it simply checks if something is present in something else - but you can "normalize" these "somethings" e.g. by converting both to lower case (or upper case, or Unicode normalized case folded or whatever is suitable for your particular application) before checking for containment.

Seeking back in the file repeatedly is extremely inefficient, though. You want to read the file into memory once:

# Normalize once, before looping
search_words = set([x.lower() for x in ['Day 3','day 3']])

with open('test-target.txt','r') as targetFile:
    contents = targetFile.read()
for search_word in search_words:
    if search_word in contents.lower():
        print('yes')
    else:
        print('no')

... or perhaps examine a line at a time:

with open('test-target.txt','r') as targetFile:
    for line in targetFile:
        for search_word in search_words:
            if search_word in line.lower():
                print('yes')
                break # maybe?
    else:
        print('no')

This will be more robust because you can handle arbitrarily large files, as long as every individual line will fit into memory.

Notice how a for loop can have an else branch, by the by.

As a usability improvement, the message you print should probably identify which search word was or wasn't found in each iteration.

Upvotes: 0

Austin
Austin

Reputation: 26039

You can use casefold() for case-insensitive search. You don't need to use seek(0) as a file pointer, by default, points to beginning of file when you open it. If you are bothered about exhausting the file pointer, read file contents to a variable, and use the variable in loop:

with open('test-target.txt','r') as targetFile:
    file_contents = targetFile.read()
    for search_word in search_words:
        if search_word.casefold() in file_contents:
            print('yes')
        else:
            print('no')

Upvotes: 1

Related Questions