dguo52001
dguo52001

Reputation: 11

ValueError in Python with for loop

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

Answers (3)

pylang
pylang

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

Burhan Khalid
Burhan Khalid

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

Matt Healy
Matt Healy

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

Related Questions