Como obter os últimos itens de uma lista em Python?
288
Preciso dos últimos 9 números de uma lista e tenho certeza de que há uma maneira de fazê-lo com o fatiamento, mas não consigo entender. Eu posso obter os 9 primeiros assim:
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")
Explicação:
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.copyelist.clear no Python 3.)
Dê um nome descritivo às suas fatias!
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 startargumento, caso contrário, seria o stopargumento .
Você pode passar o objeto de fatia para sua sequência:
islicedo módulo itertools é outra maneira possivelmente de desempenho eficiente para obter isso. islicenã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):
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 recipedef 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
R. A fatia tradicional de Python é inerente à linguagem. Esta opção funciona com sequências como strings, listas e tuplas. No entanto, esse tipo de fatia não funciona em iteradores , por exemplo iter(iterable).
B. Uma itertoolsreceita . É 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 itertoolsmódulo.
C. Muitas receitas, incluindo a última ferramenta (B), foram convenientemente implementadas em pacotes de terceiros. Instalar e importar essas bibliotecas impede a implementação manual. Uma dessas bibliotecas é chamada more_itertools(instalar via > pip install more-itertools); veja more_itertools.tail.
E. Outra ferramenta é implementada e more_itertoolsgeneralizada itertools.islicepara 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.
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 linha importante é
a[-9:]
fonte
-0
é0
. Portanto,a[-0:]
retorna inteiroa
, não os últimos zero elementos[]
. Para proteger zero, você pode usara[-n:] if n > 0 else []
.um índice negativo será contado a partir do final da lista, portanto:
fonte
Fatiamento
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:
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")
Explicação:
A notação completa é
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 é
E limpá-los é com:
(As listas obtêm
list.copy
elist.clear
no Python 3.)Dê um nome descritivo às suas fatias!
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:
O segundo argumento,,
None
é necessário, para que o primeiro argumento seja interpretado como ostart
argumento, caso contrário, seria ostop
argumento .Você pode passar o objeto de fatia para sua sequência:
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__
) areversed
.O islice permite uma avaliação lenta do pipeline de dados; assim, para materializar os dados, passe-os para um construtor (como
list
):fonte
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.
fonte
Aqui estão várias opções para obter os itens "finais" de um iterável:
Dado
Saída desejada
Código
Obtemos a última saída usando qualquer uma das seguintes opções:
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 noitertools
módulo.more_itertools
(instalar via> pip install more-itertools
); vejamore_itertools.tail
.itertools
biblioteca. Nota,itertools.islice
não suporta fatias negativas .more_itertools
generalizadaitertools.islice
para suportar o corte negativo; vejamore_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.
fonte