Come ottenere gli ultimi elementi di un elenco in Python?


Risposte:


519

A tale scopo è possibile utilizzare numeri interi negativi con l'operatore slicing. Ecco un esempio usando l'interprete CLI di 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 linea importante è a[-9:]


11
Si noti che -0è 0. Quindi a[-0:]restituisce intero a, non gli ultimi zero elementi []. Per proteggere lo zero, è possibile utilizzare a[-n:] if n > 0 else [].
Nekketsuuu,

93

un indice negativo conterà dalla fine dell'elenco, quindi:

num_list[-9:]

53

Affettare

Python slicing è un'operazione incredibilmente veloce ed è un modo pratico per accedere rapidamente a parti dei tuoi dati.

Notare la sezione per ottenere gli ultimi nove elementi da un elenco (o qualsiasi altra sequenza che lo supporti, come una stringa) sarebbe simile a questa:

num_list[-9:]

Quando vedo questo, leggo la parte tra parentesi come "9 ° dalla fine alla fine". (In realtà, l'ho abbreviato mentalmente come "-9, on")

Spiegazione:

La notazione completa è

sequence[start:stop:step]

Ma i due punti sono ciò che dice a Python che gli stai dando una fetta e non un indice normale. Ecco perché il modo idiomatico di copiare le liste in Python 2 è

list_copy = sequence[:]

E cancellarli è con:

del my_list[:]

(Gli elenchi ottengono list.copye list.clearin Python 3.)

Dai un nome descrittivo alle tue sezioni!

Potresti trovare utile separare la formazione della fetta dal passaggio al list.__getitem__metodo ( ecco cosa fanno le parentesi quadre ). Anche se non sei nuovo, mantiene il tuo codice più leggibile in modo che altri che potrebbero dover leggere il tuo codice possano capire più facilmente cosa stai facendo.

Tuttavia, non puoi semplicemente assegnare alcuni numeri separati da due punti a una variabile. Devi usare l'oggetto slice:

last_nine_slice = slice(-9, None)

È necessario il secondo argomento, in Nonemodo che il primo argomento sia interpretato come startargomento, altrimenti sarebbe l' stopargomento .

È quindi possibile passare l'oggetto slice alla sequenza:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

islice

islicedal modulo itertools è un altro modo forse performante per ottenere questo. islicenon prende argomenti negativi, così idealmente il vostro iterabile ha un __reversed__metodo speciale - quale lista non hanno - quindi è necessario prima passare la vostra lista (o iterable con __reversed__) a reversed.

>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>

islice consente una valutazione pigra della pipeline di dati, quindi per materializzare i dati, passarli a un costruttore (come list):

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

La tua abbreviazione mentale è molto utile
Swanky Coder,

40

Gli ultimi 9 elementi possono essere letti da sinistra a destra usando la lista numerica [-9:] o da destra a sinistra usando la lista numerica [: - 10: -1], come vuoi.

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

6

Ecco alcune opzioni per ottenere gli elementi "tail" di un iterabile:

Dato

n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Uscita desiderata

[2, 3, 4, 5, 6, 7, 8, 9, 10]

Codice

Otteniamo quest'ultimo output utilizzando una delle seguenti opzioni:

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

Dettagli

  • A. L' affettatura tradizionale di Python è inerente alla lingua. Questa opzione funziona con sequenze come stringhe, elenchi e tuple. Tuttavia, questo tipo di slicing non funziona su iteratori , ad esiter(iterable) .
  • B. Una itertoolsricetta . È generalizzato per funzionare su qualsiasi iterabile e risolve il problema dell'iteratore nell'ultima soluzione. Questa ricetta deve essere implementata manualmente in quanto non è ufficialmente inclusa initertools modulo.
  • C. Molte ricette, incluso quest'ultimo strumento (B), sono state convenientemente implementate in pacchetti di terze parti. L'installazione e l'importazione di queste librerie comporta l'implementazione manuale. Una di queste librerie è chiamata more_itertools(installa via > pip install more-itertools); vedi more_itertools.tail.
  • D. Un membro della itertoolsbiblioteca. Nota, itertools.islice non supporta lo slicing negativo .
  • E. Un altro strumento è implementato in more_itertoolsquanto generalizza itertools.isliceper supportare il slicing negativo; vedi more_itertools.islice_extended.

Quale uso?

Dipende . Nella maggior parte dei casi, il slicing (opzione A, come menzionato in altre risposte) è l'opzione più semplice in quanto integrata nella lingua e supporta la maggior parte dei tipi iterabili. Per gli iteratori più generali, utilizzare una delle opzioni rimanenti. Nota, le opzioni C ed E richiedono l'installazione di una libreria di terze parti, che alcuni utenti potrebbero trovare utili.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.