Nested iteration?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Apr 23 12:35:10 EDT 2013


On Tue, 23 Apr 2013 11:40:31 -0400, Roy Smith wrote:

> In reviewing somebody else's code today, I found the following construct
> (eliding some details):
> 
>     f = open(filename)
>     for line in f:
>         if re.search(pattern1, line):
>             outer_line = f.next()
>             for inner_line in f:
> 	     	if re.search(pattern2, inner_line):
>                     inner_line = f.next()
> 
> Somewhat to my surprise, the code worked.  I didn't know it was legal to
> do nested iterations over the same iterable (not to mention mixing calls
> to next() with for-loops).  Is this guaranteed to work in all
> situations?


In "all" situations? No of course not, this is Python, you can write 
nasty code that explodes the *second* time you iterate over it, but not 
the first.

class Demo:
    flag = False
    def __iter__(self):
        if self.flag:
            raise RuntimeError("don't do that!")
        self.flag = True
        return iter([1, 2, 3])


But under normal circumstances with normal iterables, yes, it's fine. If 
the object is a sequence, like lists or strings, each for-loop is 
independent of the others:

py> s = "ab"
py> for c in s:
...     for k in s:
...             print c, k
...
a a
a b
b a
b b


If the object is an iterator, each loop consumes a single value:

py> it = iter("abcd")
py> for c in it:
...     for k in it:
...             print c, k
...
a b
a c
a d


Each time you call next(), a single value is consumed. It doesn't matter 
whether you have one for-loop calling next() behind the scenes, or ten 
loops, or you call next() yourself, the same rule applies.


-- 
Steven



More information about the Python-list mailing list