python - ejemplos - django
¿Cómo obtener los últimos artículos de una lista en Python? (5)
Necesito los últimos 9 números de una lista y estoy seguro de que hay una manera de hacerlo con cortar, pero parece que no puedo obtenerlo. Puedo obtener los primeros 9 así:
num_list[0:9]
Cualquier ayuda sería genial.
Rebanar
El corte en Python es una operación increíblemente rápida, y es una forma práctica de acceder rápidamente a partes de sus datos.
La notación de división para obtener los últimos nueve elementos de una lista (o cualquier otra secuencia que lo soporte, como una cadena) se vería así:
num_list[-9:]
Cuando veo esto, leo la parte entre corchetes como "novena desde el final hasta el final". (En realidad, lo abrevia mentalmente como "-9, encendido")
Explicación:
La notación completa es
sequence[start:stop:step]
Pero el colon es lo que le dice a Python que le estás dando una porción y no un índice regular. Es por eso que la manera idiomática de copiar listas en Python 2 es
list_copy = sequence[:]
Y borrarlos es con:
del my_list[:]
(Las listas get list.copy
y list.clear
en Python 3.)
¡Dale a tus rebanadas un nombre descriptivo!
Puede resultar útil separar la formación de la porción para pasarla a la list.__getitem__
method ( eso es lo que hacen los corchetes ). Incluso si no eres nuevo en esto, mantiene tu código más legible para que otros que puedan tener que leer tu código puedan entender más fácilmente lo que estás haciendo.
Sin embargo, no puedes asignar algunos enteros separados por dos puntos a una variable. Necesitas usar el objeto slice:
last_nine_slice = slice(-9, None)
El segundo argumento, None
, es necesario, de modo que el primer argumento se interpreta como el argumento de start
contrario, sería el argumento de stop
.
A continuación, puede pasar el objeto de corte a su secuencia:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
islice
islice
del módulo itertools es otra forma posible de obtener esto. islice
no toma argumentos negativos, por lo que, idealmente, su iterable tiene un método especial __reversed__
, cuya lista sí tiene, por lo que primero debe pasar su lista (o iterable con __reversed__
) para reversed
.
>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>
islice permite la evaluación diferida de la canalización de datos, por lo que para materializar los datos, páselos a un constructor (como la list
):
>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Aquí hay varias opciones para obtener los elementos de "cola" de un iterable:
Dado:
n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Salida deseada:
[2, 3, 4, 5, 6, 7, 8, 9, 10]
Obtenemos el último resultado usando cualquiera de las siguientes opciones:
from collections import deque
import itertools
import more_itertools
# A: Slicing
iterable[-n:]
# B: Implement an itertools recipe
def tail(n, iterable):
"""Return an iterator over the last *n* items of *iterable*.
>>> t = tail(3, ''ABCDEFG'')
>>> list(t)
[''E'', ''F'', ''G'']
"""
return iter(deque(iterable, maxlen=n))
list(tail(n, iterable))
# C: Use an implemented recipe, via more_itertools
list(more_itertools.tail(n, iterable))
# D: islice, via itertools
list(itertools.islice(iterable, len(iterable)-n, None))
# E: Negative islice, via more_itertools
list(more_itertools.islice_extended(iterable, -n, None))
Descripciones
- R. El slicing tradicional de Python es inherente al lenguaje. Esta opción funciona con sequences tales como cadenas, listas y tuplas. Sin embargo, este tipo de corte no funciona en iterators , por ejemplo,
iter(iterable)
. - B. Una receta de
itertools
. Se generaliza para trabajar en cualquier iterable y resuelve el problema del iterador en la última solución. Esta receta debe implementarse manualmente ya que no está incluida oficialmente en el móduloitertools
. - C. Muchas recetas, incluida la última herramienta (B), han sido implementadas convenientemente en paquetes de terceros. Instalar e importar estas bibliotecas evita la implementación manual. Una de estas bibliotecas se llama
more_itertools
(install via> pip install more-itertools
); vermore_itertools.tail
. - D. Un miembro de la biblioteca de
itertools
. Tenga en cuenta queitertools.islice
no admiteitertools.islice
negativa . - E. Se implementa otra herramienta en
more_itertools
que generalizaitertools.islice
para soportar slicing negativo; vermore_itertools.islice_extended
.
¿Cuál uso?
Depende En la mayoría de los casos, cortar (opción A, como se menciona en otras respuestas) es la opción más sencilla ya que está integrada en el lenguaje y es compatible con la mayoría de los tipos iterables. Para iteradores más generales, use cualquiera de las opciones restantes. Tenga en cuenta que las opciones C y E requieren la instalación de una biblioteca de terceros, que algunos usuarios pueden encontrarle útil.
Los últimos 9 elementos se pueden leer de izquierda a derecha usando numlist [-9:], o de derecha a izquierda usando numlist [: - 10: -1], como desee.
>>> a=range(17)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[-9:]
[8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print a[:-10:-1]
[16, 15, 14, 13, 12, 11, 10, 9, 8]
Puede usar enteros negativos con el operador de división para eso. Aquí hay un ejemplo con el intérprete CLI de python:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> a[-9:]
[4, 5, 6, 7, 8, 9, 10, 11, 12]
la línea importante es a[-9:]
un índice negativo contará desde el final de la lista, entonces:
num_list[-9:]