Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python “return iterator”和“yield from iterator”之间的差异`_Python_Python 3.x_Itertools_Yield From - Fatal编程技术网

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