Como obter os últimos itens de uma lista em Python?


Respostas:


519

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:]


11
Note que -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 [].
nekketsuuu

93

um índice negativo será contado a partir do final da lista, portanto:

num_list[-9:]

53

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:

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:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

islice

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):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]

Sua abreviação mental é muito útil
Swanky Coder

40

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]

6

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

  • 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.
  • D. Um membro da itertoolsbiblioteca. Nota, itertools.islice não suporta fatias negativas .
  • 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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.