Ottenere l'ultimo elemento di un elenco


Risposte:


3109

some_list[-1] è il più breve e il più pitone.

In effetti, puoi fare molto di più con questa sintassi. La some_list[-n]sintassi ottiene l'ennesimo-ultimo elemento. Quindi some_list[-1]ottiene l'ultimo elemento, some_list[-2]ottiene il secondo per ultimo, ecc., Fino in fondo some_list[-len(some_list)], che ti dà il primo elemento.

È inoltre possibile impostare gli elementi dell'elenco in questo modo. Per esempio:

>>> some_list = [1, 2, 3]
>>> some_list[-1] = 5 # Set the last element
>>> some_list[-2] = 3 # Set the second to last element
>>> some_list
[1, 3, 5]

Si noti che ottenere un elemento della lista per indice aumenterà IndexErrorse l'elemento previsto non esiste. Ciò significa che some_list[-1]genererà un'eccezione se some_listè vuota, poiché un elenco vuoto non può avere un ultimo elemento.


6
Mi manca qualcosa del genere some_list.last- sarebbe una bella riga di codice
Dmitry P.

257

Se il tuo str()o gli list()oggetti potrebbero finire per essere vuoti in questo modo: astr = ''o alist = [], allora potresti voler usare alist[-1:]invece che alist[-1]per "identità" dell'oggetto.

Il significato di questo è:

alist = []
alist[-1]   # will generate an IndexError exception whereas 
alist[-1:]  # will return an empty list
astr = ''
astr[-1]    # will generate an IndexError exception whereas
astr[-1:]   # will return an empty str

Dove si fa la distinzione è che restituire un oggetto elenco vuoto o un oggetto str vuoto è più "ultimo elemento", quindi un oggetto eccezione.


26
Sottovalutato perché ritengo che il nucleo di questa risposta sia errato. Ottenere un elenco quando si desidera un elemento rimanda solo l'inevitabile "indice elenco fuori intervallo" - ed è quello che dovrebbe accadere quando si tenta di ottenere un elemento da un elenco vuoto. Per Strings astr [-1:] potrebbe essere un approccio valido poiché restituisce lo stesso tipo di astr [-1], ma non credo che ':' aiuti a gestire elenchi vuoti (e la domanda riguarda gli elenchi) . Se l'idea è di usare "alist [-1:]" come condizionale invece di "len (alist)> 0", penso che sia molto più leggibile usare la versione successiva. (felice di votare se mi mancasse qualcosa)
Stan Kurdziel,

9
Il tuo voto negativo è comprensibile e valido. Comunque trovo che ci sono due campi base su cui sono destinati gli oggetti eccezione. Una certezza è che le eccezioni bloccano la tua app. Un campo usa eccezioni nelle clausole try poiché l'altro campo userebbe invece la struttura if len (alist)> 0 :. In ogni caso, le eccezioni sono oggetti che bloccano il tuo codice. E come tale per me sono meno oggetti di sequenza come poi restituiti "null"-conseguenze che non fermano il tuo codice. La mia preferenza è quella di utilizzare le clausole IF per verificare gli oggetti "null" anziché gli oggetti che bloccano il mio codice che prelevo con una clausola try.
DevPlayer,

6
È stato votato perché la sintassi della fetta vale la discussione, tuttavia sono d'accordo con @StanKurdziel che la morfologia è sbagliata, stai solo spostando il goalpost - ho scoperto che la mia soluzione era correlata all'uso primario di 'aggiungi questo alla lista se non lo hai fatto 't già aggiungerlo' (grafici a linee delta), quindi l'espressione combinata if len(my_vector) == 0 or my_vector[-1] != update_valè un modello praticabile. ma non è certamente una soluzione globale - sarebbe bello avere una forma di sintassi in cui Nessuno fosse il risultato
Mark Mullin

17
xs[-1] if xs else None
Gabriel,

2
Perché dovresti "evitare" un IndexError? Se provi a indicizzare un elenco o una stringa vuoti, otterrai un'eccezione. Se vuoi gestire quell'eccezione, usa un tentativo / tranne: ecco a cosa serve.
Chris Johnson,

94

Puoi anche fare:

alist.pop()

Dipende da cosa vuoi fare con la tua lista perché il pop()metodo eliminerà l'ultimo elemento.


71

Il modo più semplice per visualizzare l'ultimo elemento in Python è

>>> list[-1:] # returns indexed value
    [3]
>>> list[-1]  # returns value
    3

ci sono molti altri metodi per raggiungere tale obiettivo, ma questi sono brevi e dolci da usare.


2
se la lunghezza della tua lista è zero, questa soluzione funziona mentre si list[-1]verificherà un errore.
anon01,

Che cosa? Perché dovresti fare a[-1:][0] affatto ? Fornisce a[-1]comunque anche. Spiegazione per favore?
Kaboom,

52

In Python, come si ottiene l'ultimo elemento di un elenco?

Per ottenere solo l'ultimo elemento,

  • senza modificare l'elenco e
  • supponendo che tu sappia che la lista ha un ultimo elemento (cioè non è vuoto)

passare -1alla notazione del pedice:

>>> a_list = ['zero', 'one', 'two', 'three']
>>> a_list[-1]
'three'

Spiegazione

Gli indici e le sezioni possono assumere numeri interi negativi come argomenti.

Ho modificato un esempio dalla documentazione per indicare quale elemento in una sequenza fa riferimento a ciascun indice, in questo caso, nella stringa "Python", fa -1riferimento all'ultimo elemento, il carattere 'n',:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1

>>> p = 'Python'
>>> p[-1]
'n'

Assegnazione tramite disimballaggio iterabile

Questo metodo può materializzare inutilmente un secondo elenco al solo scopo di ottenere l'ultimo elemento, ma per completezza (e poiché supporta qualsiasi iterabile - non solo elenchi):

>>> *head, last = a_list
>>> last
'three'

Il nome della variabile, head è associato all'elenco di nuova creazione non necessario:

>>> head
['zero', 'one', 'two']

Se non intendi fare nulla con quell'elenco, questo sarebbe più a proposito:

*_, last = a_list

O, davvero, se sai che è un elenco (o almeno accetta la notazione in abbonamento):

last = a_list[-1]

In una funzione

Un commentatore ha detto:

Vorrei che Python avesse una funzione per first () e last () come fa Lisp ... eliminerebbe molte funzioni lambda non necessarie.

Questi sarebbero abbastanza semplici da definire:

def last(a_list):
    return a_list[-1]

def first(a_list):
    return a_list[0]

Oppure usa operator.itemgetter:

>>> import operator
>>> last = operator.itemgetter(-1)
>>> first = operator.itemgetter(0)

In ogni caso:

>>> last(a_list)
'three'
>>> first(a_list)
'zero'

Casi speciali

Se stai facendo qualcosa di più complicato, potresti trovare più performante ottenere l'ultimo elemento in modi leggermente diversi.

Se non conosci la programmazione, dovresti evitare questa sezione, perché accoppia insieme parti di algoritmi altrimenti semanticamente diverse. Se modifichi l'algoritmo in un punto, potrebbe avere un impatto indesiderato su un'altra riga di codice.

Cerco di fornire avvertenze e condizioni il più completamente possibile, ma potrei essermi perso qualcosa. Per favore, commenta se pensi che sto lasciando un avvertimento.

Affettare

Una porzione di un elenco restituisce un nuovo elenco, quindi possiamo dividere da -1 alla fine se vogliamo l'elemento in un nuovo elenco:

>>> a_slice = a_list[-1:]
>>> a_slice
['three']

Questo ha il vantaggio di non fallire se l'elenco è vuoto:

>>> empty_list = []
>>> tail = empty_list[-1:]
>>> if tail:
...     do_something(tail)

Considerando che tentare di accedere per indice genera un IndexErrorche dovrebbe essere gestito:

>>> empty_list[-1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Ma ancora una volta, tagliare a questo scopo dovrebbe essere fatto solo se hai bisogno di:

  • un nuovo elenco creato
  • e il nuovo elenco sarà vuoto se l'elenco precedente era vuoto.

for loop

Come caratteristica di Python, non esiste un ambito interno in un forciclo.

Se stai già eseguendo un'iterazione completa sull'elenco, all'ultimo elemento verrà comunque fatto riferimento il nome della variabile assegnato nel ciclo:

>>> def do_something(arg): pass
>>> for item in a_list:
...     do_something(item)
...     
>>> item
'three'

Questa non è semanticamente l'ultima cosa nella lista. Questa è semanticamente l'ultima cosa a cui itemera legato il nome .

>>> def do_something(arg): raise Exception
>>> for item in a_list:
...     do_something(item)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 1, in do_something
Exception
>>> item
'zero'

Quindi questo dovrebbe essere usato solo per ottenere l'ultimo elemento se tu

  • sono già in loop e
  • sai che il ciclo finirà (non si interrompe o esce a causa di errori), altrimenti punterà all'ultimo elemento a cui fa riferimento il ciclo.

Ottenere e rimuoverlo

Possiamo anche mutare il nostro elenco originale rimuovendo e restituendo l'ultimo elemento:

>>> a_list.pop(-1)
'three'
>>> a_list
['zero', 'one', 'two']

Ma ora l'elenco originale è stato modificato.

( -1è in realtà l'argomento predefinito, quindi list.poppuò essere utilizzato senza un argomento indice):

>>> a_list.pop()
'two'

Fallo solo se

  • sai che l'elenco contiene degli elementi o sei pronto a gestire l'eccezione se è vuoto, e
  • hai intenzione di rimuovere l'ultimo elemento dall'elenco, trattandolo come uno stack.

Questi sono casi d'uso validi, ma non molto comuni.

Salvare il resto del contrario per dopo:

Non so perché lo faresti, ma per completezza, poiché reversedrestituisce un iteratore (che supporta il protocollo iteratore) puoi passare il risultato a next:

>>> next(reversed([1,2,3]))
3

Quindi è come fare il contrario:

>>> next(iter([1,2,3]))
1

Ma non riesco a pensare a una buona ragione per farlo, a meno che non ti serva il resto dell'iteratore inverso in seguito, che probabilmente sarebbe più simile a questo:

reverse_iterator = reversed([1,2,3])
last_element = next(reverse_iterator)

use_later = list(reverse_iterator)

e adesso:

>>> use_later
[2, 1]
>>> last_element
3

14

Per impedire IndexError: list index out of range, utilizzare questa sintassi:

mylist = [1, 2, 3, 4]

# With None as default value:
value = mylist and mylist[-1]

# With specified default value (option 1):
value = mylist and mylist[-1] or 'default'

# With specified default value (option 2):
value = mylist[-1] if mylist else 'default'


10

lst[-1]è l'approccio migliore, ma con iterabili generali, considera more_itertools.last:

Codice

import more_itertools as mit


mit.last([0, 1, 2, 3])
# 3

mit.last(iter([1, 2, 3]))
# 3

mit.last([], "some default")
# 'some default'

6

list[-1] recupererà l'ultimo elemento dell'elenco senza modificare l'elenco. list.pop()recupererà l'ultimo elemento dell'elenco, ma cambierà / modificherà l'elenco originale. Di solito, non è consigliabile mutare l'elenco originale.

In alternativa, se, per qualche motivo, stai cercando qualcosa di meno pitonico, potresti usarlo list[len(list)-1], supponendo che l'elenco non sia vuoto.


2
Probabilmente è brutto supporre che la modifica dell'elenco originale non sia generalmente raccomandata, perché, dopo tutto, viene eseguita molto comunemente
Aaron

6

È inoltre possibile utilizzare il codice riportato di seguito, se non si desidera ottenere IndexError quando l'elenco è vuoto.

next(reversed(some_list), None)

4

Ok, ma che dire del comune in quasi tutte le lingue items[len(items) - 1]? Questo è l'IMO il modo più semplice per ottenere l'ultimo elemento, perché non richiede alcuna conoscenza pitonica .


3
items [len (items) - 1] è essenzialmente ciò che Python sta facendo sotto il cofano, ma poiché la len di una sequenza è già memorizzata nella sequenza non è necessario contarla, stai creando più lavoro di quanto sia necessario.
Dan Gayle,

21
dato che stai scrivendo Python, dovresti davvero provare ad essere più Pythonic
Michael Wu,

5
@MichaelWu Non ha senso farlo. Il modo Pythonic spesso non è autoesplicativo, ha bisogno di più attenzione dove devi introdurre nuove persone per proiettare e, ovviamente, non funzionerebbe quando devi passare ad altre lingue come Java - non puoi usare le conoscenze specifiche di Python. Quando si omette il modo pitonico possibile, anche tornare al progetto dopo mesi / anni è molto più semplice.
Radek Anuszewski,

7
@Pneumokok Hai ragione, ma direi che l'indicizzazione delle liste è una tecnica Python molto semplice rispetto ai generatori. Inoltre, perché preoccuparsi di usare qualcosa di diverso da C o forse javascript se non trarrai vantaggio dai singoli strumenti di linguaggio e dalla sintassi? Quindi puoi costantemente fare tutto nel modo più duro in tutti i tuoi progetti.
Matthew Purdon,

Anche se non è molto pitonico, penso che questo sia per alcuni aspetti migliore some_list[-1]dell'approccio perché è più logico e mostra cosa sta effettivamente facendo meglio che some_list[-1]secondo me.
Byron Filer,
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.