Pregunta

¿Cuál es la mejor manera de conseguir el último elemento de un iterador en Python 2.6? Por ejemplo, digamos

my_iter = iter(range(5))

¿Cuál es la más corta de código / forma más limpia de conseguir 4 de my_iter?

Yo podría hacer esto, pero no parece muy eficiente:

[x for x in my_iter][-1]
¿Fue útil?

Solución

item = defaultvalue
for item in my_iter:
    pass

Otros consejos

Usar un deque de tamaño 1.

from collections import deque

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

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

Si está utilizando 3.x pitón:

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

si está utilizando Python 2.7:

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


Nota:

Por lo general, la solución presentada anteriormente es el lo que necesita para los casos normales, pero si se trata de gran cantidad de datos, es más eficaz utilizar una deque de tamaño 1. ( fuente )

from collections import deque

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

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

Probablemente vale la pena utilizar __reversed__ si está disponible

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

Tan simple como:

max(enumerate(the_iter))[1]

Esto es poco probable que sea más rápido que el vacío de bucle debido a la lambda, pero tal vez va a dar a alguien una idea

reduce(lambda x,y:y,my_iter)

Si el iter es vacía, se levantó una TypeError

No es esto

list( the_iter )[-1]

Si la longitud de la iteración es verdaderamente épica - tanto tiempo que la materialización de la lista agotará la memoria -. Entonces usted realmente necesidad de replantear el diseño

Yo usaría reversed, excepto que sólo se necesitan secuencias en lugar de iteradores, lo que parece bastante arbitraria.

De cualquier forma que lo hace, usted tiene que correr a través de todo el iterador. Con la máxima eficacia, si no es necesario el iterador nunca más, sólo podría basura todos los valores:

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

creo que esto es una solución sub-óptima, sin embargo.

El Toolz biblioteca proporciona una buena solución:

from toolz.itertoolz import last
last(values)

Sin embargo, la adición de una dependencia no subyacente podría no valer la pena para usarlo sólo en este caso.

Ver este código para algo similar:

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

se podría utilizar para recoger el último artículo con:

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

Yo sólo usaría next(reversed(myiter))

La pregunta es acerca de cómo obtener el último elemento de un iterador, pero si su iterador se crea mediante la aplicación de condiciones a una secuencia, entonces se invierte se puede utilizar para encontrar el "primero" de una secuencia invertida, mirando sólo los elementos necesarios , mediante la aplicación inversa para la propia secuencia.

Un ejemplo artificial,

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

Como alternativa para los iteradores infinitos que puede utilizar:

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

pensé que sería más lento que deque pero es tan rápido y es realmente más rápido que para el método de bucle (de alguna manera)

La pregunta está mal y sólo puede conducir a una respuesta que es complicado e ineficiente. Para obtener un iterador, que, por supuesto, deberá dirigir a algo que es iterable, que serán en la mayoría de los casos ofrecen una forma más directa de acceder al último elemento.

Una vez que se crea un iterador de un iterable que están atrapados en ir a través de los elementos, porque esa es la única cosa que un iterable proporciona.

Por lo tanto, la forma más eficiente y clara no es crear el iterador en el primer lugar, pero para utilizar los métodos de acceso nativos de la iterable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top