产生多个值

时间:2013-05-31 11:28:51

标签: python

我们不能在python生成器函数中产生多个值吗?

实施例,

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

感谢。

3 个答案:

答案 0 :(得分:28)

因为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(或zip):

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

答案 1 :(得分:18)

你的函数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

答案 2 :(得分:8)

使用yield from

def gen():
    for i in range(5):
        yield from (i, i+1)

[v for v in gen()]
# [0, 1, 1, 2, 2, 3, 3, 4, 4, 5]

python docs说:

使用yield from <expr>时,它将提供的表达式视为子迭代器。