3

I am trying to parse a file, in which there is a part always present, and the past part is optional.

for line in finp:
    # This part is always present
    for _ in range(int(ldata[2])):
        sdata = finp.readline()
        tdos.write(sdata)


    #This part may or may not be present
    for i in range(int(atoms)):
        next(finp)
        for j in range(int(ldata[2])):
            aatom[i][j] = [float(x) for x in
                           finp.readline().strip().split()]

The problem is, if the optional part is not present, next(finp) is giving error:

    next(finp)
StopIteration

I have tried with:

for i in range(int(atoms)):
    if i is not None:
        next(finp)
        for j in range(int(ldata[2])):
            aatom[i][j] = [float(x) for x in
                           finp.readline().strip().split()]
    else:
        break

But that does not solve the problem. I have found many previous question with same question like this, but unable to solve this problem.

Is the only way to solve it, as stated in the accepted ans is to read the whole file at once and then process?

Community
  • 1
  • 1
BaRud
  • 3,055
  • 7
  • 41
  • 89

1 Answers1

4

Give next() a default to return:

next(finp, None)

When given a second argument, next() will catch a StopIteration exception and return that second argument instead.

The alternative is to catch the StopIteration yourself; perhaps you want to break out of the loop at that point:

try:
    next(finp)
except StopIteration:
    break

Note that you are also mixing file.readline() and next(file). Because of implementation details in Python 2, you'll run into unexpected behaviour as these two methods do not share their cache. Stick to using next() here (as the for loop also treats file as an iterator). See the the File Objects documentation:

In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation), the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.

If you are using Python 3 you can disregard this warning, but you'd still be better off sticking to using one of the two approaches.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343