2017-04-20 3 views
1

ich mit dem Schreiben Dinge wie diese habe Schwierigkeiten:Warum wird ein Generator nicht umgekehrt()?

list(reversed(list(el.iterancestors()))) + [1,2,3] 

Wo Generatoren saugen, weil ich gezwungen bin, die sie in Listen zu konsumieren.

Gibt es eine Möglichkeit, dies zu vereinfachen? Ich denke, reversed() sollte einen Iterator akzeptieren, irre ich mich?

Antwort

9

Es wird nicht garantiert, dass Generatoren ein letztes Element haben, daher kann nicht umgekehrt werden. Was wäre die Ausgabe der folgenden?

from itertools import cycle 

reversed(cycle('abc')) 

Es besteht auch die Gefahr, aus Versehen alle Speicher zu essen:

from itertools import permutations 
reversed(permutations('abcdefghijklmnopqrstuvwxyz', 10)) # 19,275,223,968,000 tuples 

Beachten Sie, dass der Punkt der reversed() ist Speicher effizient zu sein. Bei Sequenzen, also Objekten mit einem Index (Listen, Strings, Tupel, Bereiche), reversed() wird ein Iterator erstellt, der einen internen Index verwendet, der bei len(inputobject) - 1 beginnt und während der Iteration bis auf 0 fortschreitet. Es muss nie eine Kopie der Eingabesequenz auf diese Weise erstellen, aber dieser Trick kann nur mit etwas funktionieren, das bereits eine Länge hat und zufälligen Zugriff unterstützt.

Für Ihren Fall Ich würde nicht reversed()sowieso verwenden. Sie möchten eine Liste als Ausgang, nicht einen Generator, so verwenden Slicing die Liste rückgängig statt:

list(el.iterancestors())[::-1] + [1, 2, 3] 

Speichereffizienz hier kein Problem ist, wie Sie eine neue Liste Objekt bauen.

Verwandte Themen