Difference between `return iterator` and `yield from iterator`

[亡魂溺海] 提交于 2019-12-05 18:03:35

Not quite.

yield from seq is equivalent to for i in seq: yield i

This means your first implementation is a generator that yields each item from the result of map(), while your second implementation returns the map object.

While they may look like very similar, even outputted with results, they are not equivalent.

Look at these basic code examples, mapping str to 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'>

The first function is a generator, yielding the results from do_yield_from and a shortened version of

for r in range(100): yield str(r)

The second function returns an instance of map, which is an iterator and not a generator.

Due to the first function being a generator, yield from has better performance than do_return

import timeit
print(timeit.timeit(do_yield_from))
>>> 0.53931242968009

print(timeit.timeit(do_return))
>>> 1.467075402143485

So my question is, are these two implementations equivalent ?

Not at all.

yield from and return are two different, distinct syntactic constructs.

yield from is syntax that was introduced in PEP380. It's called generator delegation. From the documentation:

PEP 380 adds the yield from expression, allowing a generator to delegate part of its operations to another generator. This allows a section of code containing yield to be factored out and placed in another generator. Additionally, the subgenerator is allowed to return with a value, and the value is made available to the delegating generator.

return however has completely different behavior. From the documentation:

return may only occur syntactically nested in a function definition, not within a nested class definition.

If an expression list is present, it is evaluated, else None is substituted.

return leaves the current function call with the expression list (or None) as return value.

Basically yield from <iter> is equivlent to for element in <iter>: yield element, while return will simply return a single value. In your case, I believe yield from is what you're looking for. You want to yield the values from the map iterator, not return the iterator itself.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!