Was ist der beste Weg, um das letzte Element von einem Iterator in Python 2.6 abzurufen? Zum Beispiel sagen
my_iter = iter(range(5))
Was ist der kürzeste Code / sauberste Weg, um 4
davon zu kommen my_iter
?
Ich könnte das tun, aber es scheint nicht sehr effizient zu sein:
[x for x in my_iter][-1]
python
python-3.x
python-2.7
iterator
Peter
quelle
quelle
iter(range(5))
Antworten:
quelle
None
? Genau dafürNone
ist es da. Schlagen Sie vor, dass ein funktionsspezifischer Standardwert sogar korrekt sein könnte? Wenn der Iterator Iterierte nicht wirklich, dann ein Out-of-Band - Wert ist mehr sinnvoll als einiger irreführenden funktionsspezifischen Standard.None
als Standardwert verwenden möchten , haben Sie die Wahl. Keiner ist nicht immer die vernünftigste Standardeinstellung und möglicherweise nicht einmal außerhalb der Band. Persönlich neige ich dazu, 'defaultvalue = object ()' zu verwenden, um sicherzustellen, dass es sich um einen wirklich eindeutigen Wert handelt. Ich möchte nur darauf hinweisen, dass die Auswahl der Standardeinstellung außerhalb des Bereichs dieses Beispiels liegt.None
dessen Endwert der endgültige Wert istVerwenden Sie eine
deque
Größe 1.quelle
Wenn Sie Python 3.x verwenden:
Wenn Sie Python 2.7 verwenden:
Randnotiz:
Normalerweise ist die oben vorgestellte Lösung die, die Sie für normale Fälle benötigen. Wenn Sie jedoch mit einer großen Datenmenge arbeiten, ist es effizienter, eine Lösung
deque
der Größe 1 zu verwenden. ( Quelle )quelle
*lst, last = some_iterable
._
ist eine spezielle Variable in Python und wird entweder verwendet, um den letzten Wert zu speichern oder um zu sagen, dass mir der Wert egal ist, sodass er bereinigt werden könnte.Wahrscheinlich eine Verwendung wert,
__reversed__
wenn es verfügbar istquelle
So einfach wie:
quelle
enumerate
zurückgibt(index, value)
:(0, val0), (1, val1), (2, val2)
... und dann standardmäßig,max
wenn eine Liste von Tupeln angegeben wird, nur mit dem ersten Wert des Tupels verglichen wird, es sei denn, zwei erste Werte sind gleich, die sie hier nie sind weil sie Indizes darstellen. Dann ist der nachfolgende Index, weil max das gesamte (idx, value) Tupel zurückgibt, während wir nur daran interessiert sindvalue
. Interessante Idee.Es ist unwahrscheinlich, dass dies aufgrund des Lambda schneller ist als die leere for-Schleife, aber vielleicht gibt es jemand anderem eine Idee
Wenn der Iter leer ist, wird ein TypeError ausgelöst
quelle
TypeError
für eine leere iterable zu erhöhen , können Sie auch einen Standardwert über den Anfangswert vonreduce()
zlast = lambda iterable, default=None: reduce(lambda _, x: x, iterable, default)
.Da ist das
Wenn die Länge der Iteration wirklich episch ist - so lang, dass das Materialisieren der Liste den Speicher erschöpft -, müssen Sie das Design wirklich überdenken.
quelle
ich würde ... benutzen
reversed
, außer dass es nur Sequenzen anstelle von Iteratoren braucht, was ziemlich willkürlich erscheint.Wie auch immer Sie es tun, Sie müssen den gesamten Iterator durchlaufen. Wenn Sie den Iterator bei maximaler Effizienz nie wieder benötigen, können Sie einfach alle Werte in den Papierkorb werfen:
Ich denke jedoch, dass dies eine suboptimale Lösung ist.
quelle
Die Toolz- Bibliothek bietet eine schöne Lösung:
Das Hinzufügen einer Nicht-Kern-Abhängigkeit lohnt sich jedoch möglicherweise nicht, wenn Sie sie nur in diesem Fall verwenden.
quelle
In diesem Code finden Sie etwas Ähnliches:
http://excamera.com/sphinx/article-islast.html
Sie können es verwenden, um den letzten Gegenstand abzuholen mit:
quelle
islast
in Ihrer Antwort an (siehe meta.stackexchange.com/questions/8231/… ).Ich würde nur verwenden
next(reversed(myiter))
quelle
Die Frage betrifft das Abrufen des letzten Elements eines Iterators. Wenn Ihr Iterator jedoch durch Anwenden von Bedingungen auf eine Sequenz erstellt wird, kann umgekehrt verwendet werden, um das "Erste" einer umgekehrten Sequenz zu finden, wobei nur die erforderlichen Elemente durch Anwenden betrachtet werden in umgekehrter Reihenfolge.
Ein erfundenes Beispiel,
quelle
Alternativ können Sie für unendliche Iteratoren Folgendes verwenden:
Ich dachte, es wäre dann langsamer,
deque
aber es ist genauso schnell und tatsächlich schneller als bei der Loop-Methode (irgendwie)quelle
Die Frage ist falsch und kann nur zu einer komplizierten und ineffizienten Antwort führen. Um einen Iterator zu erhalten, gehen Sie natürlich von etwas aus, das iterierbar ist und in den meisten Fällen eine direktere Möglichkeit bietet, auf das letzte Element zuzugreifen.
Sobald Sie einen Iterator aus einem Iterator erstellt haben, müssen Sie die Elemente nicht mehr durchgehen, da dies das einzige ist, was ein Iterator bietet.
Der effizienteste und klarste Weg besteht also darin, nicht zuerst den Iterator zu erstellen, sondern die nativen Zugriffsmethoden der Iterable zu verwenden.
quelle