yourknightmares
yourknightmares

Reputation: 323

Checking if a text file has another line Python

I'm working on a script to parse text files into a spreadsheet for myself, and in doing so I need to read through them. The issue is finding out when to stop. Java has a method attached when reading called hasNext() or hasNextLine() I was wondering if there was something like that in Python? For some reason I can't find this anywhere.

Ex:

open(f) as file:
    file.readline()
    nextLine = true
    while nextLine:
        file.readline()
        Do stuff
        if not file.hasNextLine():
            nextLine = false

Upvotes: 7

Views: 32772

Answers (5)

rahlf23
rahlf23

Reputation: 9019

The typical cadence that I use for reading text files is this:

with open('myfile.txt', 'r') as myfile:

    lines = myfile.readlines()

for line in lines:

    if 'this' in line: #Your criteria here to skip lines
        continue

    #Do something here

Using with will only keep the file open until you have executed all of the code within it's block, then the file will be closed. I also think it's valuable to highlight the readlines() method here, which reads all lines in the file and stores them in a list. In terms of handling newline (\n) characters, I would point you to @Joe Iddon's answer.

Upvotes: 3

Swift
Swift

Reputation: 1711

with open(filepath, 'rt+') as f:
    for line in f.readlines():
        #code to process each line

Opening it this way also closes it when it's finished which is much better on the overall memory usage, which might not matter depending on the file size.

The first lines is comparable to:

f = open(....)

f.readlines() gives you a list of all lines in the file.

The loop will start at the first line and end at then last line and shouldn't throw any errors regarding EOF for example.

[Edit]

notice the 'rt+' in the open method. As far as I'm aware this opens the file in read text mode. I.e. no decode required.

Upvotes: 3

Matthias Fripp
Matthias Fripp

Reputation: 18645

Python doesn't have an end-of-file (EOF) indicator, but you could get the same effect this way:

with open(f) as file:
    file.seek(0, 2)      # go to end of file
    eof = file.tell()    # get end-of-file position
    file.seek(0, 0)      # go back to start of file
    file.readline()
    nextLine = True      # maybe nextLine = (file.tell() != eof)
    while nextLine:
        file.readline()
        # Do stuff
        if file.tell() == eof:
            nextLine = False

But as others have pointed out, you may do better by treating the file as an iterable, like this:

with open(f) as file:
    next_line = next(file)
    # next loop will terminate when next_line is '', 
    # i.e., after failing to read another line at end of file
    while next_line:
        # Do stuff
        next_line = next(file)

Upvotes: 3

Joe Iddon
Joe Iddon

Reputation: 20434

Just use a for loop to iterate over the file object:

for line in file:
    #do stuff..

Note that this includes the new line char (\n) at the end of each line string. This can be removed through either:

for line in file:
    line = line[:-1]
    #do stuff...

or:

for line in (l[:-1] for l in file):
    #do stuff...

You can only check if the file has another line by reading it (although you can check if you are at the end of the file with file.tell without any reading).

This can be done through calling file.readline and checking if the string is not empty or timgeb's method of calling next and catching the StopIteration exception.

So to answer your question exactly, you can check whether a file has another line through:

next_line = file.readline():
if next_line:
    #has next line, do whatever...

or, without modifying the current file pointer:

def has_another_line(file):
    cur_pos = file.tell()
    does_it = bool(file.readline())
    file.seek(cur_pos)
    return does_it

which resets the file pointer resetting the file object back to its original state.

e.g.

$ printf "hello\nthere\nwhat\nis\nup\n" > f.txt
$ python -q
>>> f = open('f.txt')
>>> def has_another_line(file):
...     cur_pos = file.tell()
...     does_it = bool(file.readline())
...     file.seek(cur_pos)
...     return does_it
... 
>>> has_another_line(f)
True
>>> f.readline()
'hello\n'

Upvotes: 6

timgeb
timgeb

Reputation: 78800

Files are iterators over lines. If all you want to do is check whether a file has a line left, you can issue line = next(file) and catch the StopIeration raised in case there isn't another line. Alternatively you can use line = next(file, default) with a non-string default value (e.g. None) and then check against that.

Note that in most cases, you know that you are done when the for loop over the file ends, as the other answers have explained. So make sure you actually need that kind of fine grained control with next.

Upvotes: 1

Related Questions