Nested iteration?

Terry Jan Reedy tjreedy at udel.edu
Tue Apr 23 16:49:30 EDT 2013


On 4/23/2013 11:40 AM, 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()

Did you possibly elide a 'break' after the inner_line assignment?

> Somewhat to my surprise, the code worked.

Without a break, the inner loop will continue iterating through the rest 
of the file (billions of lines?) looking for pattern2 and re-binding 
inner-line if there is another line or raising StopIteration if there is 
not. Does this really constitute 'working'?

This is quite aside from issue of what one wants if there is no pattern1 
or if there is no line after the first match (probably not 
StopIteration) or if there is no pattern2.

> I didn't know it was legal to do nested iterations over the same iterable

Yes, but the effect is quite different for iterators (start where the 
outer iteration left off) and non-iterators (restart at the beginning).

r = range(2)
for i in r:
     for j in r:
         print(i,j)
# this is a common idiom to get all pairs
0 0
0 1
1 0
1 1

ri= iter(range(3))
for i in ri:
     for j in ri:
         print(i,j)
# this is somewhat deceptive as the outer loop executes just once
0 1
0 2

I personally would add a 'break' after 'outer_line = next(f)', since the 
first loop is effectively done anyway at that point, and dedent the 
second for statement. I find to following clearer

ri= iter(range(3))
for i in ri:
     break
for j in ri:
     print(i,j)
# this makes it clear that the first loop executes just once
0 1
0 2

I would only nest if the inner loop could terminate without exhausting 
the iterator and I wanted the outer loop to then resume.

__
Terry Jan Reedy





More information about the Python-list mailing list