Comment obtenir les derniers éléments d'une liste en Python?

Réponses:

519

Vous pouvez utiliser des entiers négatifs avec l'opérateur de découpage pour cela. Voici un exemple d'utilisation de l'interpréteur 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]

la ligne importante est a[-9:]

Winsmith
la source
11
Notez que -0c'est 0. a[-0:]Retourne donc entier a, pas les derniers éléments zéro []. Pour garder zéro, vous pouvez utiliser a[-n:] if n > 0 else [].
nekketsuuu
93

un indice négatif comptera à partir de la fin de la liste, donc:

num_list[-9:]
cobbal
la source
53

Tranchage

Le découpage Python est une opération incroyablement rapide, et c'est un moyen pratique d'accéder rapidement à des parties de vos données.

La notation de tranche pour obtenir les neuf derniers éléments d'une liste (ou de toute autre séquence qui la prend en charge, comme une chaîne) ressemblerait à ceci:

num_list[-9:]

Quand je vois cela, j'ai lu la partie entre parenthèses comme "9ème de la fin à la fin". (En fait, je l'abrège mentalement en "-9, on")

Explication:

La notation complète est

sequence[start:stop:step]

Mais le signe deux-points est ce qui indique à Python que vous lui donnez une tranche et non un index régulier. Voilà pourquoi la façon idiomatique de copier des listes en Python 2 est

list_copy = sequence[:]

Et les effacer c'est avec:

del my_list[:]

(Les listes obtiennent list.copyetlist.clear en Python 3.)

Donnez à vos tranches un nom descriptif!

Il peut être utile de séparer la formation de la tranche de sa transmission à la list.__getitem__méthode ( c'est ce que font les crochets ). Même si vous n'êtes pas nouveau, cela permet à votre code d'être plus lisible afin que les autres personnes susceptibles de lire votre code puissent plus facilement comprendre ce que vous faites.

Cependant, vous ne pouvez pas simplement affecter des entiers séparés par des deux-points à une variable. Vous devez utiliser l'objet tranche:

last_nine_slice = slice(-9, None)

Le deuxième argument,, Noneest requis, de sorte que le premier argument soit interprété comme l' startargument sinon ce serait l' stopargument .

Vous pouvez ensuite passer l'objet tranche à votre séquence:

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

islice

isliceà partir du module itertools est un autre moyen possible d'obtenir cela. islicene prend pas d' arguments négatifs, donc idéalement votre itérables a une __reversed__méthode spéciale - dont la liste ne dispose - donc vous devez d' abord passer votre liste (ou avec itérables __reversed__) à reversed.

>>> from itertools import islice
>>> islice(reversed(range(100)), 0, 9)
<itertools.islice object at 0xffeb87fc>

islice permet une évaluation paresseuse du pipeline de données, donc pour matérialiser les données, passez-les à un constructeur (comme list):

>>> list(islice(reversed(range(100)), 0, 9))
[99, 98, 97, 96, 95, 94, 93, 92, 91]
Aaron Hall
la source
Votre abréviation mentale est très utile
Swanky Coder
40

Les 9 derniers éléments peuvent être lus de gauche à droite en utilisant numlist [-9:], ou de droite à gauche en utilisant numlist [: - 10: -1], comme vous le souhaitez.

>>> 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]
Nikwin
la source
6

Voici plusieurs options pour obtenir les éléments "tail" d'un itérable:

Donné

n = 9
iterable = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Sortie désirée

[2, 3, 4, 5, 6, 7, 8, 9, 10]

Code

Nous obtenons cette dernière sortie en utilisant l'une des options suivantes:

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

Détails

  • A. Le découpage traditionnel en Python est inhérent au langage. Cette option fonctionne avec des séquences telles que des chaînes, des listes et des tuples. Cependant, ce type de découpage ne fonctionne pas sur les itérateurs , par exemple iter(iterable).
  • B. Une itertoolsrecette . Il est généralisé pour fonctionner sur n'importe quel itérable et résout le problème de l'itérateur dans la dernière solution. Cette recette doit être implémentée manuellement car elle n'est pas officiellement incluse dans le itertoolsmodule.
  • C. De nombreuses recettes, y compris le dernier outil (B), ont été commodément implémentées dans des packages tiers. L'installation et l'importation de ces bibliothèques évite l'implémentation manuelle. L'une de ces bibliothèques est appelée more_itertools(installer via > pip install more-itertools); voir more_itertools.tail.
  • D. Un membre de la itertoolsbibliothèque. Remarque: itertools.islice ne prend pas en charge le découpage négatif .
  • E. Un autre outil est mis en œuvre en more_itertoolsgénéralisant itertools.islicepour soutenir le découpage négatif; voir more_itertools.islice_extended.

Lequel dois-je utiliser?

Ça dépend . Dans la plupart des cas, le découpage (option A, comme mentionné dans d'autres réponses) est l'option la plus simple car elle est intégrée dans le langage et prend en charge la plupart des types itérables. Pour les itérateurs plus généraux, utilisez l'une des options restantes. Remarque: les options C et E nécessitent l'installation d'une bibliothèque tierce, que certains utilisateurs peuvent trouver utile.

pylang
la source