产生多个值

Shy*_*der 35 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
Run Code Online (Sandbox Code Playgroud)

其工作原理如下:

In [678]: b = a()

In [679]: list(b)
Out[679]: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
Run Code Online (Sandbox Code Playgroud)

即使我这样做也会得到相同的结果:

In [692]: def a():
    for i in range(5):
        yield i
        yield i+1
Run Code Online (Sandbox Code Playgroud)

谢谢.

Jon*_*nts 29

由于gen()回报发生器(单个项目-所以它不能被解压为两个),它需要先进的第一次得到的值...

g = gen()
a, b = next(g)
Run Code Online (Sandbox Code Playgroud)

它起作用,list因为它隐含地消耗了生成器.

我们能否进一步将其变成发电机?像这样的东西:

g = gen();
def yield_g():
    yield g.next();
    k1,k2 = yield_g();
Run Code Online (Sandbox Code Playgroud)

因此list(k1)会给予[0,1,2,3,4]list(k2)给予[1,2,3,4,5].

保留现有的发电机,并使用izip(或压缩):

from itertools import izip
k1, k2 = izip(*gen())
Run Code Online (Sandbox Code Playgroud)

  • 更新:在 Python 3.x 中,`itertools.izip` 已被内置的 `zip` 取代,因此最后一个代码块就变成了 `k1, k2 = zip(*gen)`。 (5认同)

Dav*_*ker 23

您的函数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
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我的例子是类似的,因为它使用`for`循环推进生成器.我同意乔恩的答案更加精细,并且更好地解释了什么是错误的.不过,我仍然不理解我的回答. (4认同)
  • @Marcin:我同意gen()是一个返回生成器的函数(我的第一句话确实是错误的).不过,我认为重要的是要提到生成器通常是迭代的,并且`for`循环是自然而然的事情.我同意我的答案可以从更多解释中获益. (3认同)

for*_*een 15

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]
Run Code Online (Sandbox Code Playgroud)

python文档说:

yield from <expr>被使用时,它把所提供的表达式作为subiterator。