wake-up-neo.com

Der sauberste Weg vom Python-Iterator zu erhalten

Was ist der beste Weg, um das letzte Element von einem Iterator in Python 2.6 zu erhalten? Zum Beispiel sagen Sie

my_iter = iter(range(5))

Was ist der kürzeste/sauberste Weg, um 4 von my_iter zu bekommen?

Ich könnte das tun, aber es scheint nicht sehr effizient:

[x for x in my_iter][-1]
86
Peter
item = defaultvalue
for item in my_iter:
    pass
77
Thomas Wouters

Verwenden Sie eine deque der Größe 1.

from collections import deque

#aa is an interator
aa = iter('Apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()
48
martin23487234

Wenn Sie Python 3.x verwenden:

*_, last = iterator # for a better understanding check PEP 448
print(last)

wenn Sie Python 2.7 verwenden:

last = next(iterator)
for last in iterator:
    continue
print last


NB:

Normalerweise ist die oben dargestellte Lösung das, was Sie für reguläre Fälle benötigen. Wenn Sie jedoch mit großen Datenmengen zu tun haben, ist es effizienter, eine deque der Größe 1 zu verwenden. ( Source )

from collections import deque

#aa is an interator
aa = iter('Apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()
34
DhiaTN

Wahrscheinlich lohnt sich __reversed__ wenn es verfügbar ist

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass
30
John La Rooy

So einfach wie:

max(enumerate(the_iter))[1]
19
Chema Cortes

Es ist unwahrscheinlich, dass dies aufgrund des Lambda schneller als die leere for-Schleife ist, aber vielleicht gibt es eine andere Idee

reduce(lambda x,y:y,my_iter)

Wenn der Iter leer ist, wird ein TypeError ausgelöst

19
John La Rooy

Da ist das

list( the_iter )[-1]

Wenn die Länge der Iteration wirklich episch ist - so lange das Materialisieren der Liste den Speicher erschöpft -, müssen Sie das Design wirklich überdenken.

8
S.Lott

Ich würde reversed verwenden, außer dass es nur Sequenzen anstelle von Iteratoren benötigt, was ziemlich willkürlich erscheint. 

So oder so, Sie müssen den gesamten Iterator durchlaufen. Wenn Sie den Iterator nie wieder benötigen, können Sie bei maximaler Effizienz alle Werte verwerfen:

for last in my_iter:
    pass
# last is now the last item

Ich denke jedoch, dass dies eine nicht optimale Lösung ist.

4
Chris Lutz

Sehen Sie diesen Code für etwas Ähnliches:

http://excamera.com/sphinx/article-islast.html

sie können es verwenden, um den letzten Artikel mit folgendem zu holen:

[(last, e) for (last, e) in islast(the_iter) if last]
1
James Bowman

Ich würde nur next(reversed(myiter)) verwenden.

0
thomas.mac

Alternativ können Sie für unendliche Iteratoren Folgendes verwenden:

from itertools import islice 
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples 

Ich dachte, es wäre langsamer als deque, aber es ist genauso schnell und tatsächlich schneller als bei der Schleifenmethode (irgendwie).

0
qocu

Die Bibliothek toolz bietet eine Lösung von Nice:

from toolz.itertoolz import last
last(values)

Das Hinzufügen einer Nicht-Kernabhängigkeit ist es jedoch nicht wert, nur in diesem Fall verwendet zu werden.

0
lumbric

Die Frage ist, ob das letzte Element eines Iterators abgerufen werden soll. 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, indem nur die erforderlichen Elemente angewendet werden in umgekehrter Reihenfolge.

Ein erfundenes Beispiel,

>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8
0
Wyrmwood