2014-11-25 1 views
0

Почему это не повторяется?Python `for` не перебирает объект перечисления

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) 

Выходные:

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

Docs:

Выполнить онлайн: http://goo.gl/75yuAd

+0

Try: для K, V в Перечислять (г): – Mailerdaimon

ответ

2

Любой итератор является «одним выстрелом» в том смысле, что, когда он полностью выполнен, он становится пустым и больше не может использоваться. Когда вы вызвали logging.debug(list(e)), вы использовали его в функции list() и так истощили его. Таким образом, следующая попытка использовать его в цикле for ничего не дает.

С измененным кодом, когда enumerate() вызывается снова после этого отладки, поведение скрипта изменяется - оно вызывает IndexError на y[int(k)].append(v); Я не буду исправлять это для вас, но это достаточно, чтобы начало цикла выполнялось.

+0

О мой! Конечно .. – handle

+0

_ «Любой итератор« один выстрел »в том смысле, что, когда он полностью выполнен, он становится пустым и больше не может быть использован» _: это неверно. Вы можете легко написать бесконечный итератор, и в 'itertools' есть пара элементов, таких как' count() ',' cycle() 'и' repeat() '. –

+1

@brunodesthuilliers Это не делает недействительным утверждение. Это примеры итераторов, которые не исчерпываются. – Marcin

1

эта линия:

logging.debug(list(e)) 

потребляет итератор, поэтому, когда вы получаете здесь:

for k, v in e: 
    # ... 

e уже исчерпан.

3

Потому что enumerate возвращает итератор:

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

После окончания достигается, e.next() поднимает StopIteration исключение:

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

Таким образом, вы не можете перебирать дважды e. Вам придется воссоздать итератор.

0

попробуйте вместо этого:

e = list(enumerate(d)) 
+0

Не могли бы вы добавить дополнительную информацию вместе с вашим ответом? – Max