¿Cómo obtener los últimos elementos de una lista en Python?

Necesito los últimos 9 números de una lista y estoy seguro de que hay una manera de hacerlo cortando, pero parece que no puedo entenderlo. Puedo obtener los primeros 9 de esta manera:

num_list[0:9] 

Cualquier ayuda sería genial.

Puedes usar enteros negativos con el operador de corte para eso. Aquí hay un ejemplo usando 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, por lo que:

 num_list[-9:] 

Rebanar

El corte de 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 la admita, como una cadena) se vería así:

 num_list[-9:] 

Cuando veo esto, leo la parte entre corchetes como “9 desde el final, hasta el final”. (En realidad, lo abrevio mentalmente como “-9, en”)

Explicación:

La notación completa es

 sequence[start:stop:step] 

Pero el colon es lo que le dice a Python que le está dando una porción y no un índice regular. Es por eso que la forma idiomática de copiar listas en Python 2 es

 list_copy = sequence[:] 

Y limpiarlos es con:

 del my_list[:] 

(Las listas obtienen list.copy y list.clear en Python 3.)

¡Dale a tus cortes un nombre descriptivo!

Puede que le resulte útil separar la formación de la porción de pasarla a la list.__getitem__ método list.__getitem__ ( eso es lo que hacen los corchetes ). Incluso si no es nuevo en esto, mantiene su código más legible para que otras personas que tengan que leerlo puedan entender más fácilmente lo que está haciendo.

Sin embargo, no puede simplemente 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 obligatorio, por lo 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 división 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__ – que lista tiene – por lo que primero debe pasar su lista (o iterable con __reversed__ ) a reversed .

 >>> from itertools import islice >>> islice(reversed(range(100)), 0, 9)  

islice permite una evaluación perezosa de la línea de datos, para materializar los datos, pasarlos a un constructor (como list ):

 >>> list(islice(reversed(range(100)), 0, 9)) [99, 98, 97, 96, 95, 94, 93, 92, 91] 

Los últimos 9 elementos se pueden leer de izquierda a derecha usando numlist [-9:], o de derecha a izquierda usando numlist [: – 10: -1], como quieras.

 >>> 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] 

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] 

Código

Obtenemos la última salida utilizando 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)) 

Detalles

  • A. El corte tradicional de Python es inherente al lenguaje. Esta opción funciona con secuencias como cadenas, listas y tuplas. Sin embargo, este tipo de corte no funciona en los iteradores , por ejemplo, iter(iterable) .
  • B. Una receta de itertools . Está generalizado 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ódulo de itertools .
  • C. Muchas recetas, incluida la última herramienta (B), se han implementado convenientemente en paquetes de terceros. La instalación e importación de estas bibliotecas obvia la implementación manual. Una de estas bibliotecas se llama more_itertools (instalar a través de > pip install more-itertools ); ver more_itertools.tail .
  • D. Un miembro de la biblioteca de itertools . Tenga en cuenta que itertools.islice no admite el corte negativo .
  • E. Otra herramienta se implementa en more_itertools que generaliza itertools.islice para admitir el corte negativo; ver more_itertools.islice_extended .

¿Cuál uso?

Depende En la mayoría de los casos, el corte en rodajas (opción A, como se menciona en otras respuestas) es la opción más simple, ya que está integrada en el lenguaje y admite 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 a algunos usuarios les puede resultar útil.