简体   繁体   中英

Python `for` does not iterate over enumerate object

Why does this not iterate?

import logging
logging.basicConfig(level=logging.DEBUG)

x = []
y = [[] for n in range(0, 1)]
linedata = ["0","1","2"]
x.append( linedata[0] )

d = linedata[1:] 
logging.debug( "d: {}".format(d) )
e = enumerate(d)
logging.debug( list(e) )
for k, v in e:
  logging.debug( "k:{} v:{}".format( k, v ) )
  y[int(k)].append( v )
  #for d in [(0,1)]:
  #logging.debug( "k:{} v:{}".format( d[0], d[1] ) )
  #y[d[0]].append( d[1] )

logging.debug( x )
logging.debug( y )

Output:

DEBUG:root:d: ['1', '2']
DEBUG:root:[(0, '1'), (1, '2')]
DEBUG:root:['0']
DEBUG:root:[[]]

Docs:

Run online: http://goo.gl/75yuAd

Because enumerate returns an iterator:

>>> e = enumerate(range(4))
>>> list(e)
[(0, 0), (1, 1), (2, 2), (3, 3)]
>>> list(e)
[]

Once the end is reached, e.next() raises a StopIteration exception:

>>> e.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Thus you cannot iterate twice over e . You will have to recreate the iterator.

Any iterator is "one-shot" in sense that, when it is fully executed, it becomes empty and can't be used anymore. When you called logging.debug( list(e) ) , you have used it in the list() function and so exhausted it. So, the following attempt to use it in for cycle gives nothing.

With modified code when enumerate() is called again after this debug, the script behavior gets changed - it raises IndexError on y[int(k)].append( v ) ; I won't fix this for you but this is enough sign that cycle body begins being executed.

this line :

logging.debug( list(e) )

consumes the iterator, so when you get here:

for k, v in e:
   # ...

e is already exhausted.

试试这个:

e = list(enumerate(d))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM