web-dev-qa-db-fra.com

Comment expliquer l'inverse d'une séquence par la notation de tranche a [:: - 1]

À partir du tutoriel python.org

Les indices de tranche ont des valeurs par défaut utiles; un premier index omis vaut par défaut à zéro, un deuxième index omis correspond par défaut à la taille de la chaîne à découper.

>>> a = "hello"
>>> print(a[::-1])
olleh

Comme le tutoriel le dit, a[::-1] devrait être égal à a[0:5:-1]

mais a[0:5:-1] est vide comme suit:

>>> print(len(a[0:5:-1]))
0

La question n'est pas une copie de explique-slice-notation . Cette question concerne l'utilisation générale du découpage en python.

29
Alex

Je pense que la documentation est peut-être un peu trompeuse à ce sujet, mais les arguments optionnels de slicing, si omis, sont les mêmes que ceux utilisés avec None:

>>> a = "hello"
>>> a[::-1]
'olleh'
>>> a[None:None:-1]
'olleh'

Vous pouvez voir que ces 2 tranches ci-dessus sont identiques à partir du bytecode de CPython:

>>> import dis
>>> dis.dis('a[::-1]') # or dis.dis('a[None:None:-1]')
  1           0 LOAD_NAME                0 (a)
              3 LOAD_CONST               0 (None)
              6 LOAD_CONST               0 (None)
              9 LOAD_CONST               2 (-1)
             12 BUILD_SLICE              3
             15 BINARY_SUBSCR
             16 RETURN_VALUE

Pour step négatif, les valeurs substituées pour None sont len(a) - 1 pour start et -len(a) - 1 pour end:

>>> a[len(a)-1:-len(a)-1:-1]
'olleh'
>>> a[4:-6:-1]
'olleh'
>>> a[-1:-6:-1]
'olleh'

Cela peut vous aider à visualiser:

    h  e  l  l  o   
    0  1  2  3  4  5
-6 -5 -4 -3 -2 -1
21
Chris_Rands

Tout ce qu'il fait est slice . Vous choisissez. start stop and step donc, en gros, vous dites que cela devrait commencer du début au début, mais en reculant (-1).

Si vous le faites avec -2, il sautera des lettres:

>>> a[::-2]
'olh'

Quand vous faites [0:5:-1], vous commencez à la première lettre et retournez directement à 5 et ainsi cela s’arrêtera. Ce n'est que si vous essayez [-1::-1] qu'il pourra correctement aller au début en effectuant les étapes de négatif 1.

Editer pour répondre aux commentaires

Comme l'a souligné la documentation dit

un deuxième index omis correspond par défaut à la taille de la chaîne, soit découpé en tranches. 

Supposons que nous ayons str avec len(str) = 5. Lorsque vous coupez la chaîne en omettant, laissez de côté, le deuxième nombre défini par défaut sur la longueur de la chaîne étant découpée, dans ce cas - 5 . I.e str[1:] == str[1:5], str[2:] == str[2:5]. La phrase fait référence à la longueur de l'objet d'origine et non à celui qui vient d'être coupé.

En outre, cette réponse est super

3
IsaacDj

Vous êtes confus avec le comportement de la marche. Pour obtenir le même résultat, voici ce que vous pouvez faire:

a[0:5][::-1]
'olleh'

En effet, le pas à pas veut «tourner en rond» dans votre cas, mais vous limitez son mouvement en appelant a[0:5:-1].

3
hurturk

a[0:5:-1] n'a pas beaucoup de sens, car lorsque vous utilisez cette notation, les index signifient: a[start:end:step]. Lorsque vous utilisez un pas négatif, votre valeur finale doit être à une position "antérieure" par rapport à votre valeur de départ.

2
Michele Tonutti

Vous remarquerez que le troisième argument de la tranche, le step, n'est pas présenté dans la partie du didacticiel que vous avez citée. Cet extrait suppose une étape positive.

Lorsque vous ajoutez la possibilité d'un pas négatif, le comportement est en fait assez intuitif. Un paramètre vide start fait référence à la fin de la séquence à laquelle on commence pour parcourir la séquence entière dans la direction indiquée par la valeur step. En d'autres termes, il fait référence à l'indice le plus bas (à compter) si vous avez un pas positif et à l'indice le plus élevé (à décompter) si vous avez un pas négatif. De même, un paramètre end vide se réfère à la fin de la séquence à laquelle on se retrouverait après avoir franchi la direction appropriée.

1
glibdud