Risposte:
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:]
-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 []
.
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")
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.copy
e list.clear
in Python 3.)
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 None
modo che il primo argomento sia interpretato come start
argomento, altrimenti sarebbe l' stop
argomento .
È quindi possibile passare l'oggetto slice alla sequenza:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
islice
islice
dal modulo itertools è un altro modo forse performante per ottenere questo. islice
non 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]
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]
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
iter(iterable)
.itertools
ricetta . È 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.more_itertools
(installa via > pip install more-itertools
); vedi more_itertools.tail
.itertools
biblioteca. Nota, itertools.islice
non supporta lo slicing negativo . more_itertools
quanto generalizza itertools.islice
per 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.