Odpowiedzi:
W tym celu można użyć ujemnych liczb całkowitych z operatorem krojenia. Oto przykład z użyciem interpretera CLI w Pythonie:
>>> 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]
ważną linią jest a[-9:]
-0
jest 0
. a[-0:]
Zwraca więc całe a
, a nie ostatnie zero elementów []
. Do ochrony zera możesz użyć a[-n:] if n > 0 else []
.
Wycinanie w języku Python jest niezwykle szybką operacją i jest poręcznym sposobem szybkiego dostępu do części danych.
Notacja plastra, aby uzyskać ostatnie dziewięć elementów z listy (lub dowolnej innej sekwencji, która ją obsługuje, na przykład ciąg) wyglądałaby następująco:
num_list[-9:]
Kiedy to widzę, czytam tę część w nawiasach jako „9. od końca, do końca”. (Właściwie to w myślach nazywam to „-9, on”)
Pełna notacja to
sequence[start:stop:step]
Ale dwukropek mówi Pythonowi, że dajesz mu plasterek, a nie zwykły indeks. Właśnie dlatego idiomatycznym sposobem kopiowania list w Pythonie 2 jest
list_copy = sequence[:]
I ich usunięcie polega na:
del my_list[:]
(Listy pobierają list.copy
iw list.clear
Pythonie 3).
Przydatne może być oddzielenie formowania wycinka od przekazania go do list.__getitem__
metody ( to właśnie robią nawiasy kwadratowe ). Nawet jeśli nie jesteś nowy, kod jest bardziej czytelny, dzięki czemu inni, którzy mogą przeczytać kod, mogą łatwiej zrozumieć, co robisz.
Nie można jednak po prostu przypisać zmiennej do liczb całkowitych oddzielonych dwukropkami. Musisz użyć obiektu plasterka:
last_nine_slice = slice(-9, None)
Drugi argument, None
jest wymagany, aby pierwszy argument był interpretowany jako start
argument, w przeciwnym razie byłby to stop
argument .
Następnie możesz przekazać obiekt plasterka do swojej sekwencji:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
islice
islice
z modułu itertools to kolejny możliwy sposób na uzyskanie tego. islice
nie ma negatywnych argumentów, więc idealnie swój iterable posiada __reversed__
specjalny sposób - co lista nie ma - więc trzeba najpierw zdać listy (lub z iterable __reversed__
) do reversed
.
>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>
islice pozwala na leniwą ocenę potoku danych, więc aby zmaterializować dane, przekaż je konstruktorowi (jak list
):
>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Ostatnie 9 elementów można odczytać od lewej do prawej za pomocą numlist [-9:] lub od prawej do lewej za pomocą numlist [: - 10: -1], jak chcesz.
>>> 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]
Oto kilka opcji uzyskania „ogona” elementów iterowalnych:
Dany
n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Pożądane wyjście
[2, 3, 4, 5, 6, 7, 8, 9, 10]
Kod
Ten drugi wynik uzyskujemy za pomocą jednej z następujących opcji:
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))
Detale
iter(iterable)
.itertools
Przepis . Uogólniono go do pracy na dowolnej iterowalnej i rozwiązuje problem iteratora w ostatnim rozwiązaniu. Ten przepis należy wprowadzić ręcznie, ponieważ nie jest on oficjalnie zawarty witertools
module.more_itertools
(zainstaluj przez > pip install more-itertools
); widziećmore_itertools.tail
.itertools
biblioteki. Uwaga: itertools.islice
nie obsługuje negatywnego krojenia . more_itertools
które uogólnia w itertools.islice
celu obsługi negatywnego krojenia; zob more_itertools.islice_extended
.Z którego korzystam?
To zależy . W większości przypadków krojenie (opcja A, jak wspomniano w innych odpowiedziach) jest najprostszą opcją, ponieważ jest wbudowana w język i obsługuje większość iterowalnych typów. W przypadku bardziej ogólnych iteratorów użyj dowolnej z pozostałych opcji. Uwaga: opcje C i E wymagają zainstalowania biblioteki innej firmy, co niektórzy użytkownicy mogą uznać za przydatną.