¿Cuál es la mejor manera de obtener el último elemento de un iterador en Python 2.6? Por ejemplo, di
my_iter = iter(range(5))
¿Cuál es la más corta de código / forma más limpia de conseguir 4
a partir my_iter
?
Podría hacer esto, pero no parece muy eficiente:
[x for x in my_iter][-1]
python
python-3.x
python-2.7
iterator
Pedro
fuente
fuente
iter(range(5))
Respuestas:
fuente
None
? Para esoNone
es precisamente . ¿Sugiere que algún valor predeterminado específico de la función podría incluso ser correcto? Si el iterador en realidad no itera, entonces un valor fuera de banda es más significativo que algún valor predeterminado engañoso específico de la función.None
como valor predeterminado, esa es su elección. Ninguno no siempre es el valor predeterminado más sensato y es posible que ni siquiera esté fuera de banda. Personalmente, tiendo a usar 'defaultvalue = object ()' para asegurarme de que sea un valor verdaderamente único. Solo estoy indicando que la opción predeterminada está fuera del alcance de este ejemplo.None
como valor finalUtilice una
deque
talla 1.fuente
Si está utilizando Python 3.x:
si está utilizando Python 2.7:
Nota al margen:
Por lo general, la solución presentada anteriormente es la que necesita para casos regulares, pero si está tratando con una gran cantidad de datos, es más eficiente usar un
deque
tamaño 1. ( fuente )fuente
*lst, last = some_iterable
._
es una variable especial en Python y se usa para almacenar el último valor o para decir que no me importa el valor, por lo que podría limpiarse.Probablemente valga la pena usarlo
__reversed__
si está disponiblefuente
Tan simple como:
fuente
enumerate
devuelve(index, value)
como:(0, val0), (1, val1), (2, val2)
... y luego, de manera predeterminada,max
cuando se le da una lista de tuplas, se compara solo con el primer valor de la tupla, a menos que los dos primeros valores sean iguales, que nunca están aquí porque representan índices. Entonces, el subíndice final se debe a que max devuelve la tupla completa (idx, value) mientras que solo nos interesavalue
. Idea interesante.Es poco probable que esto sea más rápido que el bucle for vacío debido a la lambda, pero tal vez le dé a otra persona una idea
Si el iter está vacío, se genera un TypeError
fuente
TypeError
para un iterable vacío, también se puede suministrar un valor predeterminado mediante el valor inicial dereduce()
, por ejemplo,last = lambda iterable, default=None: reduce(lambda _, x: x, iterable, default)
.Hay esto
Si la duración de la iteración es realmente épica, tan larga que materializar la lista agotará la memoria, entonces realmente necesitas repensar el diseño.
fuente
Yo usaría
reversed
, excepto que solo toma secuencias en lugar de iteradores, lo que parece bastante arbitrario.De cualquier forma que lo haga, tendrá que ejecutar todo el iterador. Con la máxima eficiencia, si no necesita el iterador nunca más, puede simplemente eliminar todos los valores:
Sin embargo, creo que esta es una solución subóptima.
fuente
La biblioteca toolz proporciona una buena solución:
Pero agregar una dependencia no central puede que no valga la pena por usarla solo en este caso.
fuente
Vea este código para algo similar:
http://excamera.com/sphinx/article-islast.html
puede usarlo para recoger el último artículo con:
fuente
islast
en su respuesta (consulte meta.stackexchange.com/questions/8231/… ).Yo solo usaría
next(reversed(myiter))
fuente
La pregunta es sobre cómo obtener el último elemento de un iterador, pero si su iterador se crea aplicando condiciones a una secuencia, entonces se puede usar reversed para encontrar el "primero" de una secuencia invertida, solo mirando los elementos necesarios, aplicando inversa a la secuencia en sí.
Un ejemplo artificial
fuente
Alternativamente, para iteradores infinitos puede usar:
Pensé que sería más lento entonces,
deque
pero es tan rápido y en realidad es más rápido que para el método de bucle (de alguna manera)fuente
La pregunta es incorrecta y solo puede dar lugar a una respuesta complicada e ineficaz. Para obtener un iterador, por supuesto, comienza con algo que sea iterable, que en la mayoría de los casos ofrecerá una forma más directa de acceder al último elemento.
Una vez que crea un iterador a partir de un iterable, está atrapado en el análisis de los elementos, porque eso es lo único que proporciona un iterable.
Entonces, la forma más eficiente y clara es no crear el iterador en primer lugar, sino utilizar los métodos de acceso nativos del iterable.
fuente