Strange behavior with iterables - is this a bug?

Gary Herron gherron at islandtraining.com
Wed May 31 00:30:38 CEST 2006


akameswaran at gmail.com wrote:

>Ok, I am confused about this one.  I'm not sure if it's a bug or a
>feature.. but
>  
>
List comprehension is a great shortcut, but when the shortcut starts 
causing trouble, better to go with the old ways. You need to reopen each 
file each time you want to iterate through it. You should be able to 
understand the difference between these two bits of code.

The first bit opens each file but uses (two of them) multiple times. 
Reading from a file at EOF returns an empty sequence.

The second bit opened the file each time you want to reuse it. That 
works correctly.

And that suggest the third bit of correctly working code which uses list 
comprehension.

# Fails because files are opened once but reused
f1 = open('word1.txt')
f2 = open('word2.txt')
f3 = open('word3.txt')
for i1 in f1:
  for i2 in f2:
    for i3 in f3:
      print (i1.strip(),i2.strip(),i3.strip())

and 

# Works because files are reopened for each reuse:
f1 = open('word1.txt')
for i1 in f1:
f2 = open('word2.txt')
for i2 in f2:
f3 = open('word3.txt')
for i3 in f3:
print (i1.strip(),i2.strip(),i3.strip())

and

# Also works because files are reopened for each use:
print [(i1.strip(),i2.strip(),i3.strip()) 
          for i1 in open('word1.txt')
            for i2 in open('word2.txt') 
              for i3 in open('word3.txt')]

Hope that's clear!

Gary Herron





>  
>
>>>>================================ RESTART
>>>>f1 = open('word1.txt')
>>>>f2 = open('word2.txt')
>>>>f3 = open('word3.txt')
>>>>print [(i1.strip(),i2.strip(),i3.strip(),) for i1 in f1 for i2 in f2 for i3 in f3]
>>>>        
>>>>
>[('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c')]
>  
>
>>>>l1 = ['a\n','b\n','c\n']
>>>>l2 = ['a\n','b\n','c\n']
>>>>
>>>>l3 = ['a\n','b\n','c\n']
>>>>print [(i1.strip(),i2.strip(),i3.strip(),) for i1 in l1 for i2 in l2 for i3 in l3]
>>>>        
>>>>
>[('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c'), ('a', 'b', 'a'),
>('a', 'b', 'b'), ('a', 'b', 'c'), ('a', 'c', 'a'), ('a', 'c', 'b'),
>('a', 'c', 'c'), ('b', 'a', 'a'), ('b', 'a', 'b'), ('b', 'a', 'c'),
>('b', 'b', 'a'), ('b', 'b', 'b'), ('b', 'b', 'c'), ('b', 'c', 'a'),
>('b', 'c', 'b'), ('b', 'c', 'c'), ('c', 'a', 'a'), ('c', 'a', 'b'),
>('c', 'a', 'c'), ('c', 'b', 'a'), ('c', 'b', 'b'), ('c', 'b', 'c'),
>('c', 'c', 'a'), ('c', 'c', 'b'), ('c', 'c', 'c')]
>
>explanation of code:  the files word1.txt, word2.txt and word3.txt are
>all identical conataining the letters a,b and c one letter per line.
>The lists I've added the "\n" so that the lists are identical to what
>is returned by the file objects.  Just eliminating any possible
>differences.
>
>
>If you notice, when using the file objects I don't get the proper set
>of permutations.  I was playing around with doing this via recursion,
>etc.  But nothing was working so I made a simplest case nesting.  Still
>no go.
>Why does this not work with the file objects?  Or any other class I''ve
>made which implements __iter__ and next?
>
>Seems like a bug to me, but maybe I am missing something.  Seems to
>happen in 2.3 and 2.4.
>
>  
>




More information about the Python-list mailing list