Python “return iterator”和“yield from iterator”之间的差异`
我正在尝试实现自己版本的Python “return iterator”和“yield from iterator”之间的差异`,python,python-3.x,itertools,yield-from,Python,Python 3.x,Itertools,Yield From,我正在尝试实现自己版本的itertools.compress,问题是我偶然发现了返回类型。我的意思是这两个函数都返回一个迭代器,但我认为第二个函数不被认为是生成器函数,因为里面没有yield语句。所以我的问题是,这两种实现是等价的吗 def compress (seq, selectors): from operator import itemgetter fst = itemgetter (0) snd = itemgetter (1) yield from m
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)))
不完全是
来自seq的收益率
相当于seq中i的:收益率i
这意味着您的第一个实现是一个生成器,它根据map()的结果生成每个项,而您的第二个实现返回map对象。虽然它们看起来非常相似,甚至与结果一起输出,但它们并不等价 查看这些基本代码示例,将
str
映射到range(100)
第二个函数返回map
的实例,它是迭代器,而不是生成器
由于第一个函数是生成器
,因此
的
收益率比do\u return
import timeit
print(timeit.timeit(do_yield_from))
>>> 0.53931242968009
print(timeit.timeit(do_return))
>>> 1.467075402143485
所以我的问题是,这两种实现是等价的吗
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)))
一点也不
yield from
和return
是两种不同的语法结构
yield from
是在中引入的语法。这叫做发电机授权
PEP 380添加了来自表达式的收益率,允许生成器将其部分操作委托给另一个生成器。这允许将包含收益率的代码段分解并放入另一个生成器中。此外,允许子生成器返回一个值,并且该值可供委托生成器使用
return
但是具有完全不同的行为:
返回只能以语法嵌套的方式出现在函数定义中,而不能出现在嵌套类定义中
如果存在表达式列表,则对其求值,否则不替换任何表达式列表
return以表达式列表(或None
)作为返回值保留当前函数调用
基本上,yield from
等同于for element in:yield element
,而return
只返回一个值。
在你的情况下,我相信从
中获得的收益是你想要的。您希望从映射
迭代器中产生
值,而不是返回
迭代器本身。问题是关于返回迭代器的,因此语句“返回
将只返回单个值”只是一个技术问题。从外部来看,两者都是等价的。我想严格地说,从@cube的功能来说。但仍然有区别。compress的yield from
version返回生成器对象,而return
version的compress
返回迭代器对象。正如@Wondercricket在下面指出的,使用收益率是更有效的选择。因此,至少在这种情况下,我仍然认为有必要澄清两个选项之间的区别。返回的性能差异是否相关?所需的时间相差不到一微秒。迭代时间本身要大得多;如果我们要衡量绩效,我会衡量它。(尽管这种差异可能是不相关的,也是可以忽略的。)我运行了一些测试:迭代器do_return()
上的迭代是
import timeit
print(timeit.timeit(do_yield_from))
>>> 0.53931242968009
print(timeit.timeit(do_return))
>>> 1.467075402143485