如何从生成器中获取元组?最佳实践

15

我是一名新手程序员,想要创建一个生成器,可以返回两个值,我会将其作为元组在另一个函数中使用。

我不理解为什么 tuple(function_1(a,b)) 返回 ((1,2),)tuple(function_2(a,b)) 会返回正确的元组。

我想知道发生了什么,最佳语法是什么,最终是否可能从 function_1 中检索到一个元组。

感谢您提前的任何解释!

>>> def function_1(a,b):
...     yield a,b
...
>>> def function_2(a,b):
...     yield a
...     yield b
...
>>> a = 1
>>> b = 2
>>>
>>> function_1(a,b)
<generator object function_1 at 0x1007931b0>
>>> function_2(a,b)
<generator object function_2 at 0x1007931f8>
>>> tuple(function_1(a,b))
((1, 2),)
>>> tuple(function_2(a,b))
(1, 2)
>>> for item in function_1(a,b):
...    print(item)
...
(1, 2)
>>> for item in function_2(a,b):
...    print(item)
...
1
2

1
你期望得到什么?一个包含值为(1, 2)的元组吗? - Martijn Pieters
1
我不太明白。除非我漏看什么了,Function_1 返回的是元组,而 Function_2 返回的是整数。 - Carcigenicate
你期望什么结果?第一个生成器的结果是包含单个元组(a,b)的序列,而第二个生成器的结果是包含两个元素ab的序列。 - skyking
3个回答

15

你的第一个生成器只会产出一次,并且会产出一个元组:

>>> gen = function_1(1, 2)
>>> gen = function_1(1, 2)
>>> next(gen)
(1, 2)
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

next() 函数 从迭代器中获取下一个值(生成器是特定类型的迭代器),如果有的话。当生成器完成并且无法产生更多值时,会引发 StopIteration 异常。

您的第二个生成器产生 两个分开的时间,每个时间都是一个整数:

>>> gen = function_2(1, 2)
>>> next(gen)
1
>>> next(gen)
2
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

对生成器调用tuple()将拉取生成器产生的所有值,因此对于function_1,您将获得一个包含另一个元组的元组。对于第二个生成器,您将获得包含两个整数的元组。将其与在这两个生成器上使用list()进行比较:

>>> list(function_1(1, 2))
[(1, 2)]
>>> list(function_2(1, 2))
[1, 2]

现在我们有两个列表,但第一个只包含一个元组,因为这是生成器产生的全部。

因此,这两个生成器具有根本不同的行为。选择您需要的行为;要么产生完整的元组,要么产生单独的值,但不要试图将这两种类型的输出视为相同的东西。


我不确定你是否完全理解了我的问题,但你以某种方式完美地回答了它。我的问题是关于如何调用生成器并从中获取元组的。正如你在这里演示的那样,我应该使用next()函数。 - Etienne P.

1
>>> tuple((1,2))
(1, 2)

然而在你的情况下,tuple 认为你想要创建一个包含生成器中所有值的元组。

>>> tuple(i for i in [(1, 2)])
((1, 2),)

如果你只想返回两个值,不要使用生成器。生成器用于返回不需要一次性获取的任意数量的值。


0

第一个函数返回一个元组,第二个函数返回两个单独的值。在Python中,每个逗号分隔的列表都是一个元组,括号不是必需的。因此,为了清晰明了,您可以将第一个函数写成:

def function_1(a,b):
    yield (a,b)

如果您不喜欢使用元组,那么您必须像第二个函数一样返回两个值。没有其他方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接