¿Hay alguna manera de hacer que algo como el siguiente código funcione?Python: ¿es posible mezclar generador y una función recursiva?
add = lambda n: (yield n) or add(n+1)
(respuestas no tienen que estar a la moda funcional)
¿Hay alguna manera de hacer que algo como el siguiente código funcione?Python: ¿es posible mezclar generador y una función recursiva?
add = lambda n: (yield n) or add(n+1)
(respuestas no tienen que estar a la moda funcional)
def add(n):
yield n
for m in add(n+1):
yield m
Con los generadores recursivas que es fácil de construir backtrackers elaborados:
def resolve(db, goals, cut_parent=0):
try:
head, tail = goals[0], goals[1:]
except IndexError:
yield {}
return
try:
predicate = (
deepcopy(clause)
for clause in db[head.name]
if len(clause) == len(head)
)
except KeyError:
return
trail = []
for clause in predicate:
try:
unify(head, clause, trail)
for each in resolve(db, clause.body, cut_parent + 1):
for each in resolve(db, tail, cut_parent):
yield head.subst
except UnificationFailed:
continue
except Cut, cut:
if cut.parent == cut_parent:
raise
break
finally:
restore(trail)
else:
if is_cut(head):
raise Cut(cut_parent)
...
for substitutions in resolve(db, query):
print substitutions
Este es un motor Prolog implementado por un generador recursivo. db es un dict que representa una base de datos Prolog de hechos y reglas. unify() es la función de unificación que crea todas las sustituciones para el objetivo actual y agrega los cambios al camino, por lo que se pueden deshacer más adelante. restore() realiza las pruebas de deshacer e is_cut() si el objetivo actual es un '!', por lo que podemos hacer una poda de ramas.
El ejemplo de agregar dado no tiene una condición de terminación. ¿Lo intentaste? – Alice
No estoy seguro de la intención de "rendimiento (n) o añadir (n + 1)", pero recursivos son generadores ciertamente posible. Es posible que desee leer el siguiente enlace para obtener más información sobre lo que es posible, en particular la sección titulada "Generadores recursivos".
Su función parece a mí sólo para estar otra expresión para la secuencia no unido:
n, n + 1, n + 2, ....
def add(x):
while True:
yield x
x+=1
for index in add(5):
if not index<100: break ## do equivalent of range(5,100)
print(index)
Esto no es recursivo, pero no veo la necesidad de un estilo recursivo aquí.
La versión recursiva basada en el enlace de otras respuestas, que tenían generadores de llamar a los generadores, pero no de forma recursiva:
from __future__ import generators
def range_from(n):
yield n
for i in range_from(n+1):
yield i
for i in range_from(5):
if not i<100: break ## until 100 (not including)
print i
¿Qué esperas que haga? –