3

I'm trying to find some code that, given a string, will allow me to iterate over each line using the for loop construct, but with the added requirement that separate for loop constructs will not reset the iteration back to the beginning.

At the moment I have

sList = [line for line in theString.split(os.linesep)]
for line in SList
  ... do stuff

But successive for loops will reset the iteration back to the beginning.

Does something in python exist for this, or will I have to write one from scratch?

Trent
  • 2,328
  • 3
  • 33
  • 51
  • Can you clarify a bit with some examples? Do you e.g. want to break the loop before having iterated over everything and know where you are? – Alex Brasetvik Dec 20 '09 at 23:50
  • #!/usr/bin/env /usr/bin/python import os theString = "abc\ndef" sList = [line for line in theString.split(os.linesep)] for line in sList: print line break for line in sList: print line break Should print: abc def Not abc abc – Trent Dec 22 '09 at 03:22

4 Answers4

13

Just use a generator expression (genexp) instead of the list comprehension (listcomp) you're now using - i.e.:

sList = (line for line in theString.split(os.linesep))

that's all -- if you're otherwise happy with your code (splitting by os.linesep, even though normal text I/O in Python will already have translated those into \n...), all you need to do is to use parentheses (the round kind) instead of brackets (the square kind), and you'll get a generator instead of a list.

Now, each time you do a for line in sList:, it will start again from where the previous one had stopped (presumably because of a break) -- that's what you're asking for, right?

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Ah, well done, sir. Thanks for teaching me something about the newer python features. – J.J. Dec 21 '09 at 00:01
  • What version of python was genexp introduced? We're using 2.2 at the moment, and I get a syntax error using your suggestion – Trent Dec 22 '09 at 03:36
  • @Taras, they came in with 2.4, a bit more than 5 years ago. An explicit call to `iter`, as in Federico's answer that you suggested, works in 2.2. (If you need help about a version that's 5 releases and 5 years behind, indicating it in your questions will be far more useful than belatedly mentioning it in comments;-). – Alex Martelli Dec 22 '09 at 16:40
  • Point taken - will put the version information into my next question :*) – Trent Jan 02 '10 at 00:56
2

Use another iterator:

aList = range(10)
anIterator = iter(aList)

for item in anIterator:
    print item
    if item > 4: break

for item in anIterator:
    print item
Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
0

Try using a combination of slices and enumerate():

sList = theString.split(os.linesep)
for i, line in enumerate(sList):
    if foo: 
        break

for j, line in enumerate(sList[i:]):
    # do more stuff
J.J.
  • 5,019
  • 2
  • 28
  • 26
0

Hack at an iterator?

def iterOverList(someList):
    for i in someList:
        # Do some stuff
        yield

Then just call iterOverList() within a loop a few times, it'll retain state?

Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
richo
  • 8,717
  • 3
  • 29
  • 47