2013-05-31 3 views
21

Можем ли мы дать более одного значения в функциях генератора питона?Допустимое количество значений

Пример,

In [677]: def gen(): 
    .....:  for i in range(5): 
    .....:   yield i, i+1 
    .....:   

In [680]: k1, k2 = gen() 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-680-b21f6543a7e9> in <module>() 
----> 1 k1, k2 = a() 

ValueError: too many values to unpack 

Это работает следующим образом:

In [678]: b = a() 

In [679]: list(b) 
Out[679]: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)] 

Те же результаты, даже когда я делаю это:

In [692]: def a(): 
    for i in range(5): 
     yield i 
     yield i+1 

Спасибо.

ответ

24

Потому что gen() возвращает генератор (один элемент - поэтому он не может быть распакован как два), это должно быть выдвинуто первым получить значение ...

g = gen() 
a, b = next(g) 

Он работает с list, потому что это неявно потребляет генератор.

Можем ли мы сделать это генератором? Что-то вроде этого:

g = gen(); 
def yield_g(): 
    yield g.next(); 
    k1,k2 = yield_g(); 

и поэтому list(k1) даст [0,1,2,3,4] и list(k2) даст [1,2,3,4,5].

Держите существующий генератор, и использовать izip (или индекс):

from itertools import izip 
k1, k2 = izip(*gen()) 
12

Вашей функцию gen возвращает генератор, а не значение, как вы могли бы ожидать, судя по примеру вы дали. Если вы перейдете по генератору, будут получены пары значений:

In [2]: def gen(): 
    ...:  for i in range(5): 
    ...:   yield i, i+1 
    ...:   

In [3]: for k1, k2 in gen(): 
    ...:  print k1, k2 
    ...:  
0 1 
1 2 
2 3 
3 4 
4 5 
+0

Не в этом дело. См. Ответ Джона Клемента. – Marcin

+2

Ну, мой пример похож на то, что он продвигает генератор с помощью 'for'-loop. Я согласен с тем, что ответ Джона более продуманный и имеет лучшее объяснение того, что происходит не так. Тем не менее, я по-прежнему не понимаю нисходящий ответ на мой ответ. –

+0

Можем ли мы сделать это генератором? Что-то вроде этого 'g = gen(); def yield_g(): выход g.next(); k1, k2 = yield_g(); 'и поэтому' list (k1) 'будет давать' [0,1,2,3,4] 'и' list (k2) '' [1,2,3,4,5 ] ' –

Смежные вопросы