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