'Python - find pattern in file in max 4 lines of code

i have the following task. I have to find a specific pattern(word) in my file.txt(is a song centered on page) and to print out the row number + the row which has the pattern in it getting rid of the left spaces. You can see the correct output here:


 92 Meant in croaking "Nevermore."
 99 She shall press, ah, nevermore!
107 Quoth the Raven, "Nevermore."
115 Quoth the Raven, "Nevermore."

and without this: my_str += ' '+str(count)+ ' ' + line.lstrip(), it will print:

92 Meant in croaking "Nevermore."
99 She shall press, ah, nevermore!
107 Quoth the Raven, "Nevermore."
115 Quoth the Raven, "Nevermore."

This is my code, but i want to have only 4 lines of code
```python
def find_in_file(pattern,filename):

    my_str = ''
    with open(filename, 'r') as file:
        for count,line in enumerate(file):
            if pattern in line.lower():
                if count >= 10 and count <= 99:
                    my_str += ' '+str(count)+ ' ' + line.lstrip()
                else:
                    my_str += str(count)+ ' ' + line.lstrip()


    print(my_str)


Solution 1:[1]

In fact, one line can be completed:

''.join(f' {count} {line.lstrip()}' if 10 <= count <= 99 else f'{count} {line.lstrip()}' for count, line in enumerate(file) if pattern in line.lower())

However, this seems a little too long...

According to the comment area, it can be simplified:

''.join(f'{count:3} {line.lstrip()}' for count, line in enumerate(file) if pattern in line.lower())

Solution 2:[2]

def find_in_file(pattern,filename):
    with open(filename, 'r') as file:
        # 0 based line numbering, for 1 based use enumerate(file,1)
        for count,line in enumerate(file):
            if pattern in line.lower():
                print(f"{count:>3} {line.strip()}")

would be 4 lines of code (inside the function) and should be equivalent to what you got.

Possible in one line as well:

def find_in_file(pattern,filename):
    # 1 based line numbering
    return '\n'.join(f'{count:>3} {line.strip()}' for count, line in enumerate(file,1) if pattern in line.lower())

See pythons mini format language.

Solution 3:[3]

You can use formatted strings to make sure the numbers always use three characters, even when they have only 1 or 2 digits.

I also prefer to use str.strip rather than str.lstrip, to get rid of trailing whitespace; in particular, lines read from the file will typically end with a linebreak, and then print will add a second linebreak, and we end up with too many linebreaks if we don't strip them away.

def find_in_file(pattern,filename):
    with open(filename, 'r') as file:
        for count,line in enumerate(file):
            if pattern in line.lower():
                print('{:3d} {}'.format(count, line.strip()))

find_in_file('nevermore','theraven.txt')
#  55 Quoth the Raven "Nevermore."
#  62 With such name as "Nevermore."
#  69 Then the bird said "Nevermore."
#  76 Of 'Never—nevermore'."
#  83 Meant in croaking "Nevermore."
#  90 She shall press, ah, nevermore!
#  97 Quoth the Raven "Nevermore."
# 104 Quoth the Raven "Nevermore."
# 111 Quoth the Raven "Nevermore."
# 118 Quoth the Raven "Nevermore."
# 125 Shall be lifted—nevermore!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Patrick Artner
Solution 3 Stef