Генератор Python, чтобы получить все из другого вызова генератора - PullRequest
16 голосов
/ 07 июня 2011

У меня есть генератор Python, который может вызывать сам себя, чтобы получить больше элементов для выдачи. Это выглядит так:

def gen(list):
    # ...
    if list:
        for x in gen(list[1:]):
            yield x

У меня вопрос к двум последним строкам: есть ли более краткий способ выразить это? Я надеюсь на что-то вроде этого (понимание того, что Python не верен как есть):

def gen(list):
    # ...
    if list:
        yield each in gen(list[1:])

Ответы [ 4 ]

21 голосов
/ 07 июня 2011

Был какой-то вызов для yield from или тому подобного, который "проходит" через все значения, возвращаемые подгруппой.См. PEP 380 для некоторых идей, которые были найдены.Однако пока ничего не реализовано.Ваш первый пример верен.

5 голосов
/ 07 июня 2011

Ваш пример кода очень идиоматичен и лаконичен, не требует и не имеет шансов на дальнейшие улучшения, особенно когда речь идет о читабельности.

4 голосов
/ 07 июня 2011

Ваш первый пример - правильное решение.

3 голосов
/ 03 мая 2018

Python 3.3 добавлено ключевое слово yield from . Вот сравнение между тем, что у вас есть, и кодом с новым ключевым словом:

yield_from_test.py

def gen_for(a_list):
    if a_list:
        yield a_list[0]
        for x in gen_for(a_list[1:]):
            yield x

def gen_yield(a_list):
    if a_list:
        yield a_list[0]
        yield from gen_yield(a_list[1:])

if __name__ == '__main__':
    assert list(gen_for([1,2,3])) == list(gen_yield([1,2,3]))
    print(list(gen_yield([1,2,3])))

» python3 yield_from_test.py [1, 2, 3]

...