I have a file with about 50 blocks of 14 lines, with each block starting with certain string that I can search for. Since the file is otherwise fairly large, I am using the enumerate function as:
def search_and_return_a_block(l_no,file_path, string):
with open(file_path, 'r') as file:
for l_no, line in enumerate(file):
if string in line:
#append lines into a list of 14 lines
break
return list,l_no
Now, I want only the top 2 blocks out of the 50, so when I call this function, I wish to start searching from the bottom of the 1st block and not from the beginning of the file. The function does return correct line number the first time.
However, the above for loop always start from 0 and ignores the value of its first argument (l_no) I call it with. This causes it to print only the first block 2 times and not move onto the next block.
I also tried to use the optional argument of the enumerate function with no success. Is there an elegant way to do this?
CodePudding user response:
I'm not comletely sure about what you want to achieve, and I'm no Python 2 expert (anymore), so this might not be what you are looking for:
from itertools import islice
def search_and_return_a_block(start, file_path, string):
block = []
no = start
with open(file_path, 'r') as file:
for no, line in enumerate(islice(file, start, None), start=start 1):
block.append(line.rstrip())
if string in line:
break
return block, no
If you run
start = 0
for _ in range(10):
block, start = search_and_return_a_block(start, 'file.txt', 'a')
print(block, start)
for file.txt
like
a
b
c
a
b
c
d
a
b
c
d
e
a
b
a
a
a
b
c
d
you'll get the following output:
['a'] 1
['b', 'c', 'a'] 4
['b', 'c', 'd', 'a'] 8
['b', 'c', 'd', 'e', 'a'] 13
['b', 'a'] 15
['a'] 16
['a'] 17
['b', 'c', 'd'] 20
[] 20
[] 20
But maybe a generator function would be a better fit to your needs? You could do something like:
def search_and_return_a_block(start_block, file_path, string):
with open(file_path, 'r') as file:
blocks = 1
out = True if start_block == 1 else False
block = []
for line in file:
if out:
block.append(line.rstrip())
if string in line:
yield block
block = []
elif string in line:
blocks = 1
if blocks == start_block:
out = True
When you do the following with the same file
blocks = search_and_return_a_block(2, 'file.txt', 'a')
block_2 = next(blocks)
print(block_2)
block_3 = next(blocks)
print(block_3)
the result would look like
['b', 'c', 'a']
['b', 'c', 'd', 'a']