Эквивалент `return` для генераторов Python
Иногда при переписывании рекурсивных функций в качестве генераторов я упускаю краткость return
,
"""
Returns a list of all length n strings that can be made out of a's and/or b's.
"""
def ab_star(n):
if n == 0:
return [""]
results = []
for s in ab_star(n - 1):
results.append("a" + s)
results.append("b" + s)
return results
превращается в
"""
Generator for all length n strings that can be made out of a's and/or b's.
"""
def ab_star(n):
if n == 0:
yield ""
else:
for s in ab_star(n - 1):
yield "a" + s
yield "b" + s
Это то else
это меня раздражает. Хотелось бы, чтобы был способ сказать "yield
, и это все, так что выход из функции ". Есть ли способ?
2 ответа
Не пропустите return
, используй это.
Вы можете return
сразу после тебя yield
,
def ab_star(n):
if n == 0:
yield ""
return
for s in ab_star(n - 1):
yield "a" + s
yield "b" + s
Альтернативой является использование return
в обоих случаях, когда первый случай возвращает последовательность длиной 1, а второй возвращает выражение-генератор:
def ab_star(n):
if n == 0:
return ( "", )
return ( c+s for s in ab_star(n - 1) for c in 'ab' )
Это избегание yield
избегает ограничения, что вы не можете использовать оба return <value>
а также yield
в той же функции.
(Это работает в вашем случае, потому что ваша функция не должна быть генератором. Так как вы перебираете только результаты, она также может возвращать кортеж.)
Нет Когда я писал "Простые генераторы PEP", я заметил:
Q. Then why not allow an expression on "return" too? A. Perhaps we will someday. In Icon, "return expr" means both "I'm done", and "but I have one final useful value to return too, and this is it". At the start, and in the absence of compelling uses for "return expr", it's simply cleaner to use "yield" exclusively for delivering values.
Но это никогда не получало тяги. Пока это не происходит;-), вы можете сделать ваш генератор более похожим на вашу первую функцию, написав первую часть как:
if n == 0:
yield ""
return
Тогда вы можете бросить else:
Заявление и отступление от всего остального.