deanmau5
deanmau5

Reputation: 871

Update iteration value in Python for loop

Pretty new to Python and have been writing up a script to pick out certain lines of a basic log file

Basically the function searches lines of the file and when it finds one I want to output to a separate file, adds it into a list, then also adds the next five lines following that. This then gets output to a separate file at the end in a different funcition.

What I've been trying to do following that is jump the loop to continue on from the last of those five lines, rather than going over them again. I thought the last line in the code would solved the problem, but unfortunately not.

Are there any recommended variations of a for loop I could use for this purpose?

def readSingleDayLogs(aDir): 
print 'Processing files in ' + str(aDir)    + '\n'
lineNumber = 0
try:
    open_aDirFile = open(aDir)  #open the log file
    for aLine in open_aDirFile: #total the num. lines in file
        lineNumber = lineNumber + 1
    lowerBound = 0
    for lineIDX in range(lowerBound, lineNumber):          
        currentLine = linecache.getline(aDir, lineIDX)
        if (bunch of logic conditions):
                    issueList.append(currentLine)
                    for extraLineIDX in range(1, 6): #loop over the next five lines of the error and append to issue list
                        extraLine = linecache.getline(aDir, lineIDX+ extraLineIDX) #get the x extra line after problem line
                        issueList.append(extraLine)
                    issueList.append('\n\n')
                    lowerBound = lineIDX

Upvotes: 0

Views: 17938

Answers (3)

Jon Clements
Jon Clements

Reputation: 142256

I would look at something like:

from itertools import islice

with open('somefile') as fin:
    line_count = 0
    my_lines = []
    for line in fin:
        line_count += 1
        if some_logic(line):
            my_lines.append(line)
            next_5 = list(islice(fin, 5))
            line_count += len(next_5)
            my_lines.extend(next_5)

This way, by using islice on the input, you're able to move the iterator ahead and resume after the 5 lines (perhaps fewer if near the end of the file) are exhausted.

This is based on if I'm understanding correctly that you can read forward through the file, identify a line, and only want a fixed number of lines after that point, then resume looping as per normal. (You may not even require the line counting if that's all you're after as it only appears to be for the getline and not any other purpose).

If you indeed you want to take the next 5, and still consider the following line, you can use itertools.tee to branch at the point of the faulty line, and islice that and let the fin iterator resume on the next line.

Upvotes: 0

Fabien
Fabien

Reputation: 13456

You should use a while loop :

line = lowerBound
while line < lineNumber:
    ...
    if conditions:
        ...
        for lineIDX in range(line, line+6):
           ...
        line = line + 6
    else:
        line = line + 1

Upvotes: 3

Raymond Hettinger
Raymond Hettinger

Reputation: 226764

A for-loop uses an iterator over the range, so you can have the ability to change the loop variable.

Consider using a while-loop instead. That way, you can update the line index directly.

Upvotes: 1

Related Questions