Reputation: 11
I need to make a function that returns certain lines in a file based on a list of numbers but I keep getting ValueError: Mixing iteration and read methods would lose data.
Any suggestions?
with open(path) as f:
for line in f:
if i in lst:
a = f.readline()
ans += [a.strip()]
i += 1
else:
f.readline()
i += 1
Upvotes: 0
Views: 467
Reputation: 44455
Iterating the lines in the f
should suffice:
with open(path) as f:
for i, line in enumerate(f):
if i in lst:
# do something
ans += [line.strip()]
This assumes path
, lst
and ans
are defined. Since you are iterating the lines in the file, you don't need f.readlines()
, and you don't need an incrementer. Just use enumerate
.
Note, serial list concatenations (i.e. the last line) are inefficient. Depending on what you are trying to do, look into list comprehensions, which are faster and traditionally more Pythonic. Consider @Burhan Khalid's approach.
Upvotes: 2
Reputation: 174614
You can simply this with a list comprehension:
def filter_file(filename, line_numbers):
with open(filename) as f:
return [line.strip() for idx,line in enumerate(f) if idx in line_numbers]
result = filter_file('some_file.txt', [1,5,7])
If your line_numbers
is not 0-indexed (1 is the first line), then you need to adjust the loop:
return [line.strip() for idx,line in enumerate(f) if idx+1 in line_numbers]
Upvotes: 1
Reputation: 18531
You are mixing for line in f
and f.readline()
which means you will be reading more lines than you probably intend to. To avoid this, try changing your code to something like this:
with open(path) as f:
while True:
if i in lst:
a = f.readline()
if not a:
break
ans += [a.strip()]
i += 1
else:
a = f.readline()
if not a:
break
i += 1
This way, only your readline
calls will read data from the file.
Upvotes: 0