2

I have a .txt file with 10 sort lines of text (three comma separated words each), but the following only reads four of the lines in the text file:

def main():
    path = '/path/to/file.txt'
    f  = open(path, 'r')
    for line in f:
        s = f.readline()
        print(s)
    f.close
main()

but this will read all the lines but into a list:

def main():
    path = '/path/to/file.txt'
    f  = open(path, 'r')
    s = f.readlines()
    print(s)
    f.close
main()

Why doesn't the for loop work?

Mazdak
  • 105,000
  • 18
  • 159
  • 188
iFunction
  • 1,208
  • 5
  • 21
  • 35
  • I think `for line in f` also reads a line, `f.readline()` reads the next line in line – Arjen Dijkstra Mar 23 '17 at 09:33
  • 1
    ValueError: Mixing iteration and read methods would lose data I'm stunned it works at all. – Rolf of Saxony Mar 23 '17 at 09:35
  • That's because the file objects are iterator-like objects. That means when you iterate over your object you're consuming its lines once, and in `readline` part your reading the next line. – Mazdak Mar 23 '17 at 09:38
  • Thanks for your input, for your information Rolf, it certainly didn't work well, I had no idea that the for loop already read in a line, nice to know. – iFunction Mar 23 '17 at 19:18

4 Answers4

3

When using for line in f you're already reading a line. So it's useless to do readline() since it will read the next line which explains why you get 4 lines read instead of 10.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
YGouddi
  • 341
  • 2
  • 14
  • Thanks, yes looking at it again now, I can see my loop is now reading two lines and only printing one. Taking out the s = f.readline() solved the problem. – iFunction Mar 23 '17 at 19:15
1

This would work to get all the lines:

with open('/path/to/file.txt') as fp:
    for line in fp.read().split('/n'):
        print(line)
Richy
  • 380
  • 2
  • 10
1

When you open your file.txt, you got an _io.TextIOWrapper object as f.

for line in f: will iterate on the f iterator to yield each line of your file successively,line by line, into your line variable. You can see how iterators work here.

When the f iterator moves one line after the start of your loop, you read another line with your s = f.readline() and that moves your iterator one more line ahead. When you end your first loop, another line of f is read with your for line in f: then, you skip that line by reading the next line with s = f.readline().

Your code will work with

def main():
    path = '/path/to/file.txt'
    with open(path, 'r') as f:
        for line in f:
            print(line)

main()
0

for line in f: is already iterating over the lines in the file, you are then attempting to read a line within that iteration. Just use the value of line and forget about s

Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60