Почему мой генератор не возвращает значения?


Я столкнулся с некоторым удивительным поведением с генераторами Python:

>>> def f(n):
...     if n < 2:
...         return [n]
...     for i in range(n):
...         yield i * 2
... 
>>> list(f(0))
[]
>>> list(f(1))
[]
>>> list(f(2))
[0, 2]

Почему в первых двух случаях генератор не возвращает значения?

2   3   2017-12-15 14:16:12

2 ответа:

Поскольку операторы generator return ничего не возвращают, они завершают выполнение (python знает, что это генератор, потому что он содержит по крайней мере один оператор yield). Вместо return [n] Сделайте

 yield n
 return

EDIT

После того, как я поднял этот вопрос с разработчиками python core, они указали мне на python docs , где говорится

В функции генератора оператор return указывает, что генератор выполнен и вызовет вызов StopIteration. Возвращаемое значение (если оно есть) используется в качестве аргумента для построения StopIteration и становится StopIteration.атрибут value.

Так что вы можете сделать

def f(n):
    if n < 2:
         return [n]
    for i in range(n):
         yield i * 2

g = f(1)
res = []
while True:
    try:
         res.append(next(g))
    except StopIteration as e:
         if e.value is not None:
              res = e.value
         break

Если вы действительно, действительно хотели.

return не генерирует iterator. используйте yield , а затем return

def f(n):
        if n < 2:
            yield n
            return
        for i in range(n):
            yield i * 2