93 votes

Inverser une liste en utilisant la notation en tranches

Dans l'exemple suivant :

foo = ['red', 'white', 'blue', 1, 2, 3]

donde: foo[0:6:1] imprimera tous les éléments de foo. Cependant, foo[6:0:-1] omettra le 1er ou le 0e élément.

>>> foo[6:0:-1]
[3, 2, 1, 'blue', 'white']

Je comprends que je peux utiliser foo.reverse() ou foo[::-1] pour imprimer la liste en sens inverse, mais j'essaie de comprendre pourquoi foo[6:0:-1] n'imprime pas la liste entière ?

4 votes

Notez également le foo[7:None:-1] possibilité :)

1 votes

Je n'ai jamais utilisé Python auparavant, j'essaie juste de comprendre la notation des tranches, ma question est de savoir pourquoi foo[6:0:-1] n'envoie pas d'erreur d'index, est-ce que Python ne s'en soucie pas ? parce que l'index 6 n'est pas disponible dans le tableau de l'exemple ci-dessus.

3 votes

@MubasharAhmad Le découpage n'est pas une indexation et ne génère pas d'erreur en cas de dépassement des limites. En revanche, l'indexation envoie une exception en cas de dépassement des limites.

179voto

Andrew Clark Points 77748

La notation des tranches en bref :

[ <first element to include> : <first element to exclude> : <step> ]

Si vous voulez inclure le premier élément lorsque vous inversez une liste, laissez l'élément du milieu vide, comme ceci :

foo[::-1]

Vous pouvez également trouver de bonnes informations sur les tranches de Python en général ici :
Expliquer la notation des tranches de Python

48 votes

Ceci : [ <first element to include> : <first element to exclude> : <step> ] est l'explication la plus claire de la syntaxe des tranches que j'ai vue. Le fait d'appeler cela "premier élément à exclure" rend vraiment évident ce qui se passe.

0 votes

Qu'en est-il du découpage négatif avec des étapes négatives ? Je ne comprends toujours pas.

7 votes

Lorsque vous utilisez un indice négatif comme <first element to include> o <first element to exclude> il indexe depuis le début de la liste, donc -1 est le dernier élément, -2 est l'avant-dernier élément, etc. Ainsi, par exemple, x[-1:-4:-1] obtiendrait les trois derniers éléments de x dans l'ordre inverse. Vous pourriez donc interpréter cela comme "reculer en prenant chaque élément ( -1 pas) du dernier élément de la liste ( -1 <first element to include> ) jusqu'au quatrième élément en partant de la fin, mais sans l'inclure ( -4 <first element to include> )".

15voto

Captain Lepton Points 86

Si vous avez du mal à vous souvenir de la notation de la tranche, vous pouvez essayer de faire l'opération suivante Hokey Cokey :

[ Sur : Out : Tout est dans le shake ]

[Premier élément à sur clude : Premier élément à partir out : Le site étape à utiliser]

YMMV

7voto

Fred Nurk Points 8927

...pourquoi foo[6:0:-1] n'imprime pas la liste entière ?

Parce que la valeur moyenne est la exclusif plutôt qu'une valeur limite inclusive. Le site notation des intervalles est [start, stop].

C'est exactement comme cela que fonctionne [x]range :

>>> range(6, 0, -1)
[6, 5, 4, 3, 2, 1]

Ce sont les indices qui sont inclus dans votre liste résultante, et ils n'incluent pas 0 pour le premier élément.

>>> range(6, -1, -1)
[6, 5, 4, 3, 2, 1, 0]

Une autre façon de voir les choses est :

>>> L = ['red', 'white', 'blue', 1, 2, 3]
>>> L[0:6:1]
['red', 'white', 'blue', 1, 2, 3]
>>> len(L)
6
>>> L[5]
3
>>> L[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

L'indice 6 est au-delà (à une unité près) des indices valides pour L, ce qui l'exclut de la plage comme valeur d'arrêt exclue :

>>> range(0, 6, 1)
[0, 1, 2, 3, 4, 5]

Vous obtenez toujours des indices pour chaque élément de la liste.

6voto

Emreu Points 103

Cette réponse est peut-être un peu dépassée, mais elle pourrait être utile à quelqu'un qui est confronté au même problème. Vous pouvez obtenir une liste inverse avec une fin arbitraire - jusqu'à l'indice 0, en appliquant la deuxième tranche in-place comme ceci :

>>> L = list(range(10))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (start_ex, end) = (7, 0)
>>> L[end:start_ex][::-1]
[6, 5, 4, 3, 2, 1, 0]

1 votes

C'est en fait assez utile, car vous pouvez utiliser la même syntaxe pour tous les cas. Vous n'avez pas à traiter 0 comme un cas particulier.

0 votes

Cela a plus de sens que le comportement par défaut de Python/numpy pour le découpage négatif, car normalement on veut découper et/ou inverser une image ou un tenseur aligné sur un bord donné, alors que Python/numpy perd la dernière ligne/colonne des données o_O.

1voto

miwi Points 11

Vous pouvez le faire fonctionner si vous utilisez une valeur d'arrêt négative. Essayez ceci :

foo[-1:-7:-1]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X