C'est une histoire bien connue (j'oublie souvent) que peu importe la taille ou la petite spécification d'un nombre dans une tranche Python, une erreur d'index ne se produit pas, mais la raison en est "** Il le gère bien en interne. ** «Je pensais que je ne pouvais pas trouver un article en japonais expliquant ce qui précède, alors j'ai décidé de l'écrire comme une industrie de l'écart.
Dans cet article, j'expliquerai le thème du sujet sous deux angles: ** idée ** et ** implémentation . J'espère me débarrasser de la maladie des personnes qui sont novices en Python et qui pensent que " Erreur d'indexation lors de l'extraction d'un élément spécifique May est considérée comme une tranche, mais ce n'est pas une tranche **". Je vais.
De plus, étant donné que l'auteur lui-même est inexpérimenté, je vous serais reconnaissant de bien vouloir signaler toute inexactitude dans les expressions pour une étude ultérieure.
Cette section correspond à la partie idée du tranchage. Même dans le document officiel, «qu'est-ce qu'une tranche» n'est pas écrit clairement (semble-t-il), mais c'est frustrant, mais il y a pour l'instant l'explication suivante.
--Remarque sur s [i: j]
Une tranche de> s de i à j est définie comme une séquence d'éléments avec un indice k tel que i <= k <j.
--Note sur s [i: j: k]
La "tranche de i à j avec étapes k"> s est constituée d'éléments avec un index x = i + n * k (où n est tout entier qui satisfait 0 <= n <(ji) / k). Défini comme une séquence.
Intégré - Documentation Python 3.8.5
Vous pouvez le comprendre si vous le lisez correctement, mais c'est un peu ennuyeux.
Si vous extrayez uniquement ce dont vous avez besoin maintenant, le découpage signifie-t-il que "créer une nouvelle ** séquence ** composée de ** éléments ** correspondant à l'index spécifié ** à partir de la séquence d'origine"?
(Une séquence est un type de données tel que liste, taple, plage, chaîne, chaîne d'octets, etc.)
Voici une citation de Stack Overflow expliquant pourquoi c'est important.
Indexing returns a single item, but slicing returns a subsequence of items. So when you try to index a nonexistent value, there's nothing to return. But when you slice a sequence outside of bounds, you can still return an empty sequence.
https://stackoverflow.com/a/9490148
En d'autres termes
Je dis ça. J'ai mentionné 1 ci-dessus, donc je ne pense pas qu'il soit nécessaire de l'expliquer, mais qu'en est-il de 2?
En bref, «[0,1,2] [3]» est ** une erreur car il n'y a pas de valeur de retour **, mais «[0,1,2] [3:]» est un élément correspondant à l'indice 3 ou supérieur. S'il n'y a pas de ** liste vide, []
peut être renvoyée comme valeur de retour, il n'est donc pas nécessaire de faire une erreur **.
Cela dit, les personnes d'Antoinette (y compris l'auteur) lisant ceci ont dit: "** Si vous devez avoir une valeur de retour, vous pouvez renvoyer None avec [0,1,2] [3]
. Vous pourriez penser: "Ce n'est pas bon **".
Cependant, dans ce cas, il est possible de déterminer si ** [0,1,2] [3]
renvoie None ou [0,1,2, None] [3]
renvoie None ** J'ai encore besoin d'une erreur d'index car cela devient plus difficile (et l'a gentiment complétée dans la suite de la citation précédente).
L'explication a peut-être été un peu redondante, mais la conclusion était que l'erreur "** slice peut retourner une séquence vide même s'il n'y a pas d'élément correspondant **" ne se produit pas.
(Jabashi: Cela me donne envie d'utiliser des termes comme "sous-ensemble / sous-chaîne" et "ensemble vide", mais quand je dis "ensemble", ignorez l'élément de type séquence "ordre". Après tout, il n'y a pas d'autre choix que de l'expliquer comme le document officiel.)
Cette section correspond à la partie implémentation de la tranche.
Comment gérez-vous des opérations comme «[P, y, t, h, o, n] [100: 200]» d'une «bonne manière»? La réponse est une continuation de la citation du document officiel dans la section précédente. Il est caché dans la pièce.
--Remarque sur s [i: j]
Si> i ou j est supérieur à len (s), utilisez len (s). Si i est omis ou Aucun, utilisez 0. Si j est omis ou None, utilisez len (s). Si i est supérieur ou égal à j, la tranche sera une séquence vide.
En d'autres termes, dans «[P, y, t, h, o, n] [100: 200]», «len (s)» est utilisé parce que «i» et «j» sont tous deux plus grands que «len (s)». Alors, ʻi (= len (s))> = j (= len (s)) `tient, donc il est jugé qu'une séquence vide est retournée.
[Les tranches sont également indexées en interne](https://qiita.com/tanuk1647/items/276d2be36f5abb8ea52e#How les tranches sont converties en index), donc elles sont plus grandes que len (s)
Les nombres sont convertis à l'avance. Lorsque «step» est spécifié, le même traitement est essentiellement effectué.
Enfin, je vais vous donner une référence sur la façon dont le traitement ici est implémenté dans CPython. Je ne suis pas fort en C non plus, donc je pense que vous devriez le regarder dans la mesure où "Ah, c'est définitivement écrit comme ça" (aussi dans le code source / * c'est plus difficile à comprendre que vous ne le pourriez Il dit penser * /
).
(Dans cette section, nous avons expliqué le cas où step
n'est pas utilisé, mais dans le code de devis, c'est le processus lorsque step
est utilisé. Je ne sais pas.)
sliceobject.c
defstop = *step < 0 ? -1 : length;
...
if (r->stop == Py_None) {
*stop = defstop;
}
...
if ((*step < 0 && *stop >= *start)
|| (*step > 0 && *start >= *stop)) {
*slicelength = 0;
cpython: 3a1db0d2747e Objects/sliceobject.c
Le tranchage est pratique.
Merci d'avoir regardé jusqu'à la fin.
Intégré - Documentation Python 3.8.5 [Python] Résumé du fonctionnement de la tranche --Qiita python - Why does substring slicing with index out of range work? - Stack Overflow string - Why python's list slicing doesn't produce index out of bound error? - Stack Overflow
Recommended Posts