web-dev-qa-db-fra.com

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

J'ai besoin des 9 derniers chiffres d'une liste et je suis sûr qu'il y a un moyen de le faire en découpant, mais je n'arrive pas à l'obtenir. Je peux obtenir les 9 premiers comme ceci:

num_list[0:9]

Toute aide est la bienvenue.

233
Nope

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

426
winsmith

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

num_list[-9:]
84
cobbal

Tranchage

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

La notation par tranches 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, je lis la partie entre parenthèses comme "9ème de la fin, à la fin." (En fait, je l'abrévie mentalement en "-9, sur")

Explication:

La notation complète est

sequence[start:stop:step]

Mais ce sont les deux points qui disent à Python que vous lui donnez une tranche et non un index régulier. C’est pourquoi la manière idiomatique de copier des listes dans Python 2 est

list_copy = sequence[:]

Et les nettoyer est avec:

del my_list[:]

(Les listes reçoivent list.copy et list.clear dans Python 3.)

Donnez à vos tranches un nom descriptif!

Vous pouvez trouver utile de séparer la coupe de la transmettre à la méthode list.__getitem__ ( , comme le font les crochets ). Même si vous n’êtes pas novice, le code reste plus lisible, ce qui permettra aux autres utilisateurs qui l’ont peut-être lue de comprendre plus facilement ce que vous faites.

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

last_nine_slice = slice(-9, None)

Le deuxième argument, None, est requis pour que le premier argument soit interprété comme l'argument start, sinon il s'agirait de l'argument stop .

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

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

islice

islice du module itertools est un autre moyen potentiellement performant d’obtenir cela. islice ne prend pas d'arguments négatifs, donc idéalement, votre itérable a une méthode spéciale __reversed__ - la liste utilisée par - vous devez d'abord passer votre liste (ou itérable avec __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. Pour matérialiser les données, transmettez-les à un constructeur (comme list):

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

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]
38
Nikwin

Voici plusieurs options pour obtenir les "queues" d’itéré:

Étant 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. Traditionnel Python découpage en tranches est inhérent au langage. Cette option fonctionne avec séquences tels que des chaînes, des listes et des tuples. Cependant, ce type de découpage ne fonctionne pas sur itérateurs , par ex. iter(iterable).
  • B. Une itertools recette . Il est généralisé de travailler sur toutes les itérations et de résoudre le problème d'itérateur dans la dernière solution. Cette recette doit être implémentée manuellement car elle n’est pas officiellement incluse dans le module itertools.
  • C. De nombreuses recettes, y compris le dernier outil (B), ont été implémentées de manière pratique dans des packages tiers. L'installation et l'importation de ces bibliothèques suppriment l'implémentation manuelle. L'une de ces bibliothèques s'appelle _more_itertools_ (installation via _> pip install more-itertools_); voir more_itertools.tail .
  • D. Un membre de la bibliothèque itertools. Remarque, _itertools.islice_ ne prend pas en charge le découpage négatif .
  • E. Un autre outil implémenté dans _more_itertools_ généralise _itertools.islice_ pour prendre en charge le découpage négatif; voir more_itertools.islice_extended .

Lequel dois-je utiliser?

Cela dépend . Dans la plupart des cas, le découpage en tranches (l'option A, comme indiqué dans d'autres réponses) est l'option la plus simple, car elle est intégrée au langage et prend en charge les types les plus 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, ce que certains utilisateurs peuvent trouver utile.

4
pylang