Domanda

Qual è il modo migliore di ottenere l'ultimo elemento da un iteratore in Python 2.6? Ad esempio, dire

my_iter = iter(range(5))

Qual è il più breve codice / modo più pulito di ottenere 4 da my_iter?

ho potuto fare questo, ma non sembra molto efficace:

[x for x in my_iter][-1]
È stato utile?

Soluzione

item = defaultvalue
for item in my_iter:
    pass

Altri suggerimenti

deque di taglia 1.

from collections import deque

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

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

Se si utilizza python 3.x:

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

se si utilizza python 2.7:

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


NB:

Di solito la soluzione presentata sopra è la cosa avete bisogno per i casi normali, ma se avete a che fare con grandi quantità di dati, è più efficiente di utilizzare una deque di dimensioni 1. ( fonte )

from collections import deque

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

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

Probabilmente vale la pena utilizzare __reversed__ se è disponibile

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

Per quanto semplice:

max(enumerate(the_iter))[1]

Questa è improbabile che sia più veloce del vuoto per ciclo a causa della lambda, ma forse sarà dare a qualcun altro un'idea

reduce(lambda x,y:y,my_iter)

Se l'iter è vuota, viene sollevata un'eccezione TypeError

C'è questo

list( the_iter )[-1]

Se la lunghezza dell'iterazione è veramente epico - così a lungo che materializzando la lista esaurirà la memoria -., Allora si ha realmente bisogno di ripensare il design

userei reversed, tranne che richiede solo sequenze invece di iteratori, che sembra piuttosto arbitraria.

In qualsiasi modo lo si fa, si dovrà eseguire attraverso l'intero iteratore. Alla massima efficienza, se non è necessario sempre di nuovo l'iteratore, si può solo buttare tutti i valori:

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

Credo che questa è una soluzione non ottimale, però.

Il Toolz libreria fornisce una bella soluzione:

from toolz.itertoolz import last
last(values)

Ma aggiungere una dipendenza non-core potrebbe non essere la pena per usarlo solo in questo caso.

Vedere questo codice per qualcosa di simile:

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

si potrebbe utilizzarlo per raccogliere l'ultimo elemento con:

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

Vorrei solo usare next(reversed(myiter))

La domanda è su come ottenere l'ultimo elemento di un iteratore, ma se il vostro iteratore è creato mediante l'applicazione di condizioni a una sequenza, quindi invertito può essere usato per trovare la "prima" di una sequenza invertita, solo guardando gli elementi necessari , applicando invertire la sequenza stessa.

Un esempio forzato,

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

In alternativa, per infinite iteratori è possibile utilizzare:

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

Ho pensato che sarebbe stato più lento di deque ma è più veloce e in realtà è più veloce quindi per il metodo loop (in qualche modo)

La domanda è sbagliato e può solo portare ad una risposta che è complicato e inefficiente. Per ottenere un iteratore, è ovviamente avvia fuori da qualcosa che è iterabile, che nella maggior parte dei casi, offrire un modo più diretto di accedere l'ultimo elemento.

Una volta creato un iteratore da un iterabile si sono bloccati nel passare attraverso gli elementi, perché questa è l'unica cosa che un iterabile fornisce.

Quindi, il modo più efficace e chiara non è creare l'iteratore, in primo luogo, ma di utilizzare i metodi di accesso nativi del iterabile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top