2013-05-31 34 views
21

Python üreteci işlevlerinde birden fazla değer sağlayamıyor musunuz? aşağıdaki gibiBirden çok değer katsayısı

Örnek,

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 

Bu çalışır:

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

Teşekkür: Bunu

In [678]: b = a() 

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

aynı sonuçlar bile.

cevap

24

gen() Çünkü döner bir jeneratör (tek bir öğe - bu yüzden ikisi kadar paketten olamaz), bu It ile çalışır

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

... ilk değerlerini almak için gelişmiş olması gerekir list, çünkü bu, üreteci dolaylı olarak tüketir.

Bunu bir jeneratör yapabilir miyiz? Böyle bir şey:

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

ve bu nedenle list(k1)[0,1,2,3,4] verecekti ve list(k2)[1,2,3,4,5] verecekti.

mevcut jeneratör tutun ve izip (veya zip) kullanın: Eğer verdi Örneğin bakarsak Tahmin edebileceğiniz gibi bir jeneratör olup değerleri döndürür gen

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

Sizin fonksiyonu. Jeneratör üzerinde yineleme yaparsanız, değer çiftleri verilecektir:

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

Bu kadar değil. Jon Clements'ın yanıtını görün. – Marcin

+2

Eh, benim örneğim benzer, çünkü bir 'for'-loop kullanarak jeneratörü ilerletir. Jon'un cevabının daha ayrıntılı olduğunu ve neyin yanlış gittiğini daha iyi açıkladığına katılıyorum. Yine de cevabımdaki düşüşü hala anlamadım. –

+0

Bunu bir jeneratör daha yapabilir miyiz? Böyle bir şey 'g = gen(); verim_g(): verim g.next(); k1, k2 = verim_g(); 've bu nedenle' liste (k1) '' [0,1,2,3,4] 've' liste (k2) '' [1,2,3,4,5 verir. ] –

İlgili konular