我正在尝试实现我自己版本的itertools.compress,问题是我偶然发现了返回类型。我的意思是,这两个函数都返回一个迭代器,但我认为第二个函数不被视为生成器函数,因为其中没有yield语句。所以我的问题是,这两个实现是等价的吗?
def compress (seq, selectors):
from operator import itemgetter
fst = itemgetter (0)
snd = itemgetter (1)
yield from map (fst, filter (snd, zip (seq, selectors)))
def compress (seq, selectors):
from operator import itemgetter
fst = itemgetter (0)
snd = itemgetter (1)
return map (fst, filter (snd, zip (seq, selectors)))发布于 2017-08-11 02:14:57
不完全是。
yield from seq等同于for i in seq: yield i
这意味着您的第一个实现是一个生成器,它从map()的结果中产生每个项目,而您的第二个实现返回map对象。
发布于 2017-08-11 02:23:05
虽然它们可能看起来非常相似,即使输出的是结果,但它们并不等价。
看看这些将str映射到range(100)的基本代码示例
def do_yield_from():
yield from map(str, range(100))
def do_return():
return map(str, range(100))
print(do_yield_from())
print(do_return())
>>> <class 'generator'>
>>> <class 'map'>第一个函数是一个generator,它产生来自do_yield_from的结果和
for r in range(100): yield str(r)第二个函数返回map的一个实例,该实例是一个iterator而不是generator。
由于第一个函数是generator,因此yield from的性能比do_return更好
import timeit
print(timeit.timeit(do_yield_from))
>>> 0.53931242968009
print(timeit.timeit(do_return))
>>> 1.467075402143485发布于 2017-08-11 02:30:18
所以我的问题是,这两个实现是等价的吗?
不用谢。
yield from和return是两种不同、截然不同的语法结构。
yield from是在PEP380中引入的语法。这被称为生成器委托。From the documentation
PEP380添加了
yield from表达式,允许生成器将其部分操作委托给另一个生成器。这允许包含yield的一段代码被分解出来,并放在另一个生成器中。此外,允许子生成器返回一个值,并且委托生成器可以使用该值。
然而,return有完全不同的行为。From the documentation
返回只能以语法方式嵌套在函数定义中,而不能嵌套在类定义中。
如果存在表达式列表,则对其求值,否则不替换任何表达式。
return将当前的函数调用保留为表达式列表(或None)作为返回值。
基本上,yield from <iter>等同于for element in <iter>: yield element,而return只返回单个值。在您的情况下,我相信yield from就是您要找的东西。您希望yield来自map迭代器的值,而不是return迭代器本身。
https://stackoverflow.com/questions/45620608
复制相似问题