Python: Verwenden eines rekursiven Algorithmus als Generator
Kürzlich schrieb ich eine Funktion zu generieren, die bestimmte Sequenzen mit nicht-triviale Einschränkungen. Das problem kam mit einem natürlichen rekursive Lösung. Jetzt ist es passiert, dass selbst für relativ kleine Eingang, die Sequenzen sind mehrere Tausende, so würde ich es vorziehen zu verwenden, meinen Algorithmus als generator, anstatt es zu füllen eine Liste mit allen Sequenzen.
Hier ist ein Beispiel. Nehmen wir an, wir wollen berechnen alle Permutationen eines Strings mit einer rekursiven Funktion. Der folgende naive Algorithmus nimmt ein zusätzliches argument 'storage' und fügt eine permutation auf, Wann immer er eine findet:
def getPermutations(string, storage, prefix=""):
if len(string) == 1:
storage.append(prefix + string) # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], storage, prefix+string[i])
storage = []
getPermutations("abcd", storage)
for permutation in storage: print permutation
(Please don ' T care über Ineffizienz, dies ist nur ein Beispiel.)
Nun ich möchte meine Funktion in einen generator, d.h. Sie liefern eine permutation statt anfügen an die Liste "datenspeicher":
def getPermutations(string, prefix=""):
if len(string) == 1:
yield prefix + string # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], prefix+string[i])
for permutation in getPermutations("abcd"):
print permutation
Dieser code ist nicht Arbeit (die Funktion verhält sich wie eine leere generator).
Bin ich etwas fehlt?
Gibt es eine Möglichkeit, schalten Sie die oben genannten rekursiven Algorithmus in einen generator , ohne Sie zu ersetzen mit einem iterativen man?
InformationsquelleAutor der Frage Federico A. Ramponi | 2008-10-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Oder ohne Akku:
InformationsquelleAutor der Antwort Markus Jarderot
Dies vermeidet die
len(string)
-Tiefe der Rekursion, und ist im Allgemeinen eine schöne Art und Weise zu handhaben Generatoren-innen-Generatoren:flatten
ermöglicht es uns, auch weiterhin Fortschritte in einem anderen generator, indem Sie einfachyield
ing es, statt des Durchlaufens undyield
ing jedem Element manuell.Python 3.3 hinzufügen
Ertrag
der syntax, die es erlaubt, Natürliche delegation zu einem sub-generator:InformationsquelleAutor der Antwort ephemient
Den inneren Ruf, getPermutations-es ist ein generator, zu.
Müssen Sie Durchlaufen, die mit einer for-Schleife (siehe @MizardX posting, das kantige mir aus von Sekunden!)
InformationsquelleAutor der Antwort S.Lott