JahaJA
JahaJA

Reputation: 13

Iterating over line index and printing the full line

I have this (kind of) big text file in which i have to find specific lines that tells the current action. For some of those lines I have find another line (usually 4-6 lines beneath) that tells information of said action. My current script looks like this:

fileLines = file.readlines()
nrlines = enumerate(fileLines)
for i,line in nrlines:
    if "TiltArmAxis::StateGoingToAlmostUp" in line:
        print "%d - %s" % (i, line)
        for i,line in range(i, i+7):
            if "Axis::StatePositionMode:" in line:
                print "%d - %s" % (i, line)

It works in the first for but not in the second, I get:

4520 - "2014-11-13 08:13:43",T:305310  TiltArmAxis - changing state from TiltArmAxis::StateAtDown -> TiltArmAxis::StateGoingToAlmostUp

But then:

for i,line in range(i, i+7):
TypeError: unpack non-sequence

So basically, I want to fist index every line with enumerate, then find the lines with "TiltArmAxis::StateGoingToAlmostUp" in them and print. Then look in the next 6 lines for "Axis::StatePositionMode:" and if such line occur (if not, skip it); print it and go to next "TiltArmAxis::StateGoingToAlmostUp".

Is there a more effective way of doing this? Please help

EDIT: Removed args,

range(i, i+7):

Still get the same error

Upvotes: 1

Views: 2311

Answers (2)

dlask
dlask

Reputation: 8992

We can simply index the list of lines.

with open("test.txt", "rt") as f:
    lines = f.readlines()
    for i in range(len(lines)):
        if "TiltArmAxis::StateGoingToAlmostUp" in lines[i]:
            print "%d - %s" % (i, lines[i])
            for j in range(i, min(i+7, len(lines))):
                if "Axis::StatePositionMode:" in lines[j]:
                    print "%d - %s" % (j, lines[j])

Alternatively, we can still use enumerate:

with open("test.txt", "rt") as f:
    lines = f.readlines()
    for i, line in enumerate(lines):
        if "TiltArmAxis::StateGoingToAlmostUp" in line:
            print "%d - %s" % (i, line)
            for j, line in enumerate(lines[i:i+7]):
                if "Axis::StatePositionMode:" in line:
                    print "%d - %s" % (i+j, line)

And finally a solution that doesn't load the whole file to RAM. It's based on assumption that the string "TiltArmAxis::StateGoingToAlmostUp" doesn't appear again in the next 6 lines.

with open("test.txt", "rt") as f:
    look_for_next = False
    for i, line in enumerate(f):
        if look_for_next:
            if i < limit:
                if "Axis::StatePositionMode:" in line:
                    print "%d - %s" % (i, line)
                    look_for_next = False
            else:
                look_for_next = False
        else:
            if "TiltArmAxis::StateGoingToAlmostUp" in line:
                print "%d - %s" % (i, line)
                look_for_next = True
                limit = i + 7

Upvotes: 1

Serge Ballesta
Serge Ballesta

Reputation: 149085

range(i, i+7) is a simple sequence of integers between i and i+7. What you need is :

nrlines = enumerate(file)
for i,line in nrlines:
    if "TiltArmAxis::StateGoingToAlmostUp" in line:
        print "%d - %s" % (i, line)
        for j in range(7):
            i, line = next(nrlines)  # use next on the iterator !
            if "Axis::StatePositionMode:" in line:
                print "%d - %s" % (i, line)

BTW, you should protect the next with a try: ... except StopIteration: ... to avoid error if you reach end of file during the inner loop. I cannot do it, because I do not really know what you want to do in except case :-)

Upvotes: 0

Related Questions