0

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
6
  • 1
    One line 3, what is i? Commented Feb 19, 2017 at 4:41
  • variable that starts at 0 Commented Feb 19, 2017 at 4:42
  • i have a text file and a list of numbers. I need to return only the lines corresponding to those numbers. Commented Feb 19, 2017 at 4:43
  • Is the list sorted? Commented Feb 19, 2017 at 4:44
  • 4
    You can use either for line in f: or .readline(), not both. Commented Feb 19, 2017 at 4:44

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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]

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.