Python >> Tutoriel Python >  >> Python

Pourquoi le découpage avec un index hors plage fonctionne-t-il en Python ?

Le découpage en Python signifie accéder à une sous-séquence d'un type de séquence en utilisant la notation [start:end] . Une caractéristique peu connue du découpage est qu'il possède des indices de fin robustes . Le découpage est robuste même si le end index est supérieur à l'indice de séquence maximal. La tranche prend juste tous les éléments jusqu'à l'élément maximal. Si l'index de départ est également hors limites, il renvoie la tranche vide.

Slicing :arrêter l'index hors limites et démarrer l'index dans les limites

Que se passe-t-il si l'index de début d'une opération de découpage donnée est dans les limites alors que l'index d'arrêt est à l'extérieur ?

Dans ce cas, le découpage prendra en compte tous les éléments jusqu'à l'indice maximal possible. Comme il ne peut pas trancher davantage sur des éléments inexistants, il s'arrête et renvoie gracieusement la tranche à laquelle il a déjà accédé.

Voici un exemple pour une chaîne :

>>> s = 'hello'
>>> s[1:100]
'ello'
>>> s[3:100]
'lo'

Voici un exemple de liste :

>>> lst = [1, 2, 3]
>>> lst[1:100]
[2, 3]
>>> lst[3:100]
[]

Le dernier exemple lst[3:100] est expliqué ensuite !

Slicing :démarrer et arrêter l'index hors limites

L'opération de découpage ne génère pas d'erreur si vos indices de démarrage et d'arrêt sont supérieurs à la longueur de la séquence. Cela contraste avec l'indexation simple - si vous indexez un élément qui est hors limites, Python lancera une erreur d'index hors limites. Cependant, avec le découpage, il renvoie simplement une séquence vide.

Voici un exemple pour une chaîne :

>>> s = 'hello'
>>> s[100:200]
''

Et voici un exemple pour une liste :

>>> lst = [1, 2, 3]
>>> lst[100:200]
[]

Voici ce qui se passe si vous essayez d'indexer un élément en dehors des limites :

>>> lst = [1, 2, 3]
>>> lst[100]
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    lst[100]
IndexError: list index out of range

Pourquoi le découpage hors limites n'entraîne-t-il pas d'erreur ? [Motivation de conception]

Vous pouvez trouver la décision de conception des créateurs de Python étrange qu'ils génèrent une erreur si vous indexez hors des limites, mais ils ne le font pas si vous coupez hors des limites.

Il n'y a pas de science exacte ici, mais je trouve la décision très sensée pour les raisons suivantes.

L'indexation est censée toujours renvoyer un seul élément. Le découpage est censé renvoyer une sous-séquence d'un nombre variable d'éléments. Si vous indexez un élément inexistant, il n'y a rien à retourner et Python doit générer une erreur - tout le reste n'aurait aucun sens. Mais si vous découpez une séquence hors limites, il est parfaitement logique de renvoyer une séquence vide.

Oui, vous pouvez renvoyer None dans le cas de l'indexation. Cependant, cela rendrait impossible de différencier les deux cas où un None élément est stocké dans une liste et où une liste n'a pas d'élément du tout.

La documentation en montre la raison ultime :

"La tranche de s à partir de i à j avec l'étape k est défini comme la séquence d'éléments avec l'indice x = i + n*k tel que 0 <= n < (j-i)/k . En d'autres termes, les indices sont i , i+k , i+2*k , i+3*k et ainsi de suite, en s'arrêtant à j est atteint (mais n'incluant jamais j ). Quand k est positif, i et j sont réduits à len(s) s'ils sont plus grands "

Ceci explique clairement pourquoi la sémantique est telle qu'elle est :dans notre cas, les indices i et j sont réduits à len(s) . Donc, vous avez une tranche de len(s) à len(s) exclus qui est la séquence vide par définition.

Puzzle de découpage :testez vos compétences

Pouvez-vous résoudre le casse-tête suivant sur les indices de dépassement Python ?

word = "galaxy"
print(word[4:50])

Quel est le résultat de cet extrait de code ?

Vous pouvez vérifier votre solution par rapport à notre étalon-or sur l'application Finxter.com et suivre vos compétences.

Documentation officielle

Si vous voulez placer dans les docs qui pointent vers l'explication de ce problème, c'est ici :

"Les indices de tranche dégénérés sont gérés avec élégance :un index trop grand est remplacé par la taille de la chaîne, une borne supérieure plus petite que la borne inférieure renvoie une chaîne vide. ” – Documentation officielle de Python 3

>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''

Vidéo associée