Respostas:
Você pode usar números inteiros negativos com o operador de fatiamento para isso. Aqui está um exemplo usando o interpretador CLI 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]
a linha importante é a[-9:]
-0
é 0
. Portanto, a[-0:]
retorna inteiro a
, não os últimos zero elementos []
. Para proteger zero, você pode usar a[-n:] if n > 0 else []
.
O fatiamento em Python é uma operação incrivelmente rápida e é uma maneira útil de acessar rapidamente partes de seus dados.
A notação de fatia para obter os últimos nove elementos de uma lista (ou qualquer outra sequência que a suporte, como uma string) ficaria assim:
num_list[-9:]
Quando vejo isso, li a parte entre parênteses como "9ª do fim até o fim". (Na verdade, eu abrevio isso mentalmente como "-9, em")
A notação completa é
sequence[start:stop:step]
Mas o cólon é o que diz ao Python que você está dando uma fatia e não um índice regular. É por isso que a maneira idiomática de copiar listas no Python 2 é
list_copy = sequence[:]
E limpá-los é com:
del my_list[:]
(As listas obtêm list.copy
elist.clear
no Python 3.)
Você pode achar útil separar a formação da fatia da passagem para o list.__getitem__
método ( é isso que os colchetes fazem ). Mesmo se você não é novo nele, ele mantém seu código mais legível, para que outras pessoas que precisam ler seu código possam entender mais facilmente o que está fazendo.
No entanto, você não pode simplesmente atribuir alguns números inteiros separados por dois pontos a uma variável. Você precisa usar o objeto de fatia:
last_nine_slice = slice(-9, None)
O segundo argumento,, None
é necessário, para que o primeiro argumento seja interpretado como o start
argumento, caso contrário, seria o stop
argumento .
Você pode passar o objeto de fatia para sua sequência:
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
islice
islice
do módulo itertools é outra maneira possivelmente de desempenho eficiente para obter isso. islice
não leva argumentos negativos, portanto o ideal seria o seu iterable tem um __reversed__
método especial - que lista não tem - por isso você deve primeiro passar por sua lista (ou iterable com __reversed__
) a reversed
.
>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>
O islice permite uma avaliação lenta do pipeline de dados; assim, para materializar os dados, passe-os para um construtor (como list
):
>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Os últimos 9 elementos podem ser lidos da esquerda para a direita usando o numlist [-9:] ou da direita para a esquerda usando o numlist [: - 10: -1], conforme desejado.
>>> 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]
Aqui estão várias opções para obter os itens "finais" de um iterável:
Dado
n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Saída desejada
[2, 3, 4, 5, 6, 7, 8, 9, 10]
Código
Obtemos a última saída usando qualquer uma das seguintes opções:
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))
Detalhes
iter(iterable)
.itertools
receita . É generalizado para trabalhar em qualquer iterável e resolve o problema do iterador na última solução. Esta receita deve ser implementada manualmente, pois não está oficialmente incluída no itertools
módulo.more_itertools
(instalar via > pip install more-itertools
); veja more_itertools.tail
.itertools
biblioteca. Nota, itertools.islice
não suporta fatias negativas . more_itertools
generalizada itertools.islice
para suportar o corte negativo; veja more_itertools.islice_extended
.Qual eu uso?
Depende . Na maioria dos casos, o fatiamento (opção A, como mencionado em outras respostas) é a opção mais simples, pois é incorporado ao idioma e suporta os tipos mais iteráveis. Para iteradores mais gerais, use qualquer uma das opções restantes. Observe que as opções C e E exigem a instalação de uma biblioteca de terceiros, que alguns usuários podem achar úteis.