发电机和功能

时间:2016-12-12 22:06:24

标签: python python-3.x generator

我不确定这里发生了什么。今天是我第一次涉足发电机世界。我把它放到了pythontutor visualizer中,但我不明白为什么会这样。可视化器吐出“生成器返回实例”。我已经阅读了与我类似的其他SO线程,但遗憾的是我不明白为什么会这样。除了这个特定的问题,我非常感谢有关学习如何正确有效地使用发电机的好方法的任何想法。谢谢!

def even(nums):
    for number in nums:
        if number % 2 == 0:
             yield number


def find_evens(number_list):
    return even(number_list)

>>> find_evens([1,2,3,4,5,6])
<generator object even at 0x104f7af10>

3 个答案:

答案 0 :(得分:2)

Python REPL只是为您提供生成器对象的默认表示。

生成器本身不会产生它的值,你必须强制它。存在许多强制选项,例如将其包装在list

list(find_evens([1,2,3,4,5,6]))
[2, 4, 6]

或者,类似地,通过迭代:

for i in find_evens([1, 2, 3, 4, 5, 6]):
    print(i)

这些示例(循环,调用list)都会在生成器对象上调用__next__,强制它根据您编写的语句返回下一个值。

至于有关这些的更多信息,您可以随时查看Python wiki Page on Generator.

答案 1 :(得分:2)

生成器对象的方法为__next__()

此方法必须被调用(显式或隐式获取其下一个值

(在某些情境中使用生成器对象耗尽隐式重复 - 如for中所示循环或list()函数。)

创建生成器对象后:

  • __next__()方法的第一次使用返回 1st yield语句的值,
  • __next__()方法的第二次使用返回第二 yield语句的值,
  • .......
  • 依此类推 - 直到没有其他yield语句,在这种情况下生成器对象 耗尽(和useless)因为它从这一刻开始 - 而不是下一个值 - 只有异常StopIteration

比较

>>> even([1, 2, 3, 4, 5, 6]).__next__()
2
>>> even([1, 2, 3, 4, 5, 6]).__next__()
2
>>> even([1, 2, 3, 4, 5, 6]).__next__()
2

>>> gen = even([1, 2, 3, 4, 5, 6])
>>>
>>> gen.__next__()
2
>>> gen.__next__()
4
>>> gen.__next__()
6
>>> gen.__next__()
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    gen.__next__()
StopIteration
>>>
>>> gen.__next__()
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    gen.__next__()
StopIteration

在第一种情况下一次又一次地创建生成器 ,而在第二种情况下,它创建一次然后重复使用< em>直到耗尽(还有1次 - 仅用于说明)。

答案 2 :(得分:0)

您可以想象您只获得指向生成器所在位置的指针。通过打印,您可以打印它所在的位置。但要实际获取值,您必须说给我值,然后通过执行list或在for循环中使用它来执行此操作。