Рекурсия с использованием урожая

Есть ли способ смешать рекурсию и инструкцию yield ? Например, генератор бесконечного числа (с использованием рекурсии) будет выглядеть примерно так:

 def infinity(start): yield start # recursion here ... >>> it = infinity(1) >>> next(it) 1 >>> next(it) 2 

Я пытался:

 def infinity(start): yield start infinity(start + 1) 

а также

 def infinity(start): yield start yield infinity(start + 1) 

Но никто из них не сделал то, что я хочу, первый остановился после того, как он дал start а второй дал start , затем генератор, а затем остановился.

ПРИМЕЧАНИЕ. Пожалуйста, я знаю, что вы можете сделать это, используя цикл while:

 def infinity(start): while True: yield start start += 1 

Я просто хочу знать, можно ли это сделать рекурсивно.

  • Статический метод Python не всегда можно вызывать
  • Вложенные инструкции if-else Python
  • Поддержка шаблонов бутылок?
  • Как конвертировать CRLF в LF на машине Windows в Python
  • Более простой способ включения подробного ведения журнала
  • Невозможно получить cx_Oracle для работы с Python версии 2.7 / mac os 10.7.2 (Lion) - missing_OCIAttrGet
  • Python: поиск файла в текущем каталоге и всех его родителей
  • Psycopg2 Поддержка протокола Python не скомпилирована в
  • 3 Solutions collect form web for “Рекурсия с использованием урожая”

    Да, ты можешь это сделать:

     def infinity(start): yield start for x in infinity(start + 1): yield x 

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

    Начиная с Python 3.3, вы сможете использовать

     def infinity(start): yield start yield from infinity(start + 1) 

    Если вы просто вызываете функцию генератора рекурсивно, не зацикливая на ней или не yield from нее, все, что вы делаете, это сборка нового генератора без фактического запуска тела функции или получения чего-либо.

    Подробнее см. PEP 380 .

    В некоторых случаях было бы предпочтительнее использовать стек вместо рекурсии для генераторов. Должна быть возможность переписать рекурсивный метод с использованием стека и цикла while.

    Ниже приведен пример рекурсивного метода, который использует обратный вызов и может быть переписан с использованием логики стека:

     def traverse_tree(callback): # Get the root node from somewhere. root = get_root_node() def recurse(node): callback(node) for child in node.get('children', []): recurse(child) recurse(root) 

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

    Метод можно использовать таким образом, распечатывая некоторое свойство на каждом узле.

     def callback(node): print(node['id']) traverse_tree(callback) 

    Вместо этого используйте стек и напишите метод обхода в качестве генератора

     # A stack-based alternative to the traverse_tree method above. def iternodes(): stack = [get_root_node()] while stack: node = stack.pop() yield node for child in node.get('children', []): stack.append(child) 

    Теперь вы можете получить то же поведение, что и traverse_tree выше, но с генератором:

     for node in iternodes(): print(node['id']) 

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

    Таким образом, в основном вам просто нужно добавить цикл for, где вам нужно рекурсивно вызывать вашу функцию . Это относится к Python 2.7.

    Python - лучший язык программирования в мире.