Pourquoi ne sous-chaîne de découpage avec l'index hors de portée?
Pourquoi ne pas 'example'[999:9999]
entraîner dans l'erreur? Depuis 'example'[9]
fait, quelle est la motivation qui est derrière?
De ce comportement, je peux supposer que 'example'[3]
est, en substance/à l'interne, pas le même que 'example'[3:4]
, même si les deux résultats dans le même 'm'
chaîne.
[999:9999]
n'est pas un indice, c'est une tranche, et ont des sémantiques différentes. À partir du python intro: "Dégénéré tranche indices sont traitées correctement: un index qui est trop grand est remplacée par la taille de la chaîne, une limite supérieure plus petite que la limite inférieure retourne une chaîne vide."- c'est la réponse exacte
- Et savez-vous pourquoi c'est de cette façon? Je vous remercie pour vos éclaircissements.
- Pourquoi? Vous devriez demander à Guido, mais je pense que c'est élégant pour être en mesure d'assumer une tranche est toujours le même type de séquence de la séquence d'origine, moi-même.
- Yep, c'est vrai. Je pense que j'ai mal compris [a:b] comme si c'était un [a..b] genre de chose...
- Quelqu'un a effectivement utilisé ce comportement dans le code réel? Tranches de représenter un sous-ensemble de listes d'index et par définition un sous-ensemble est inclus dans l'ensemble. Pour moi, si foo = [0,1,2,3] et je tranche foo[-42:1337] qu'il ressemble plus à un bug que comme une intention de le trancher. La chose est que nous avons eu de merveilleux objets pour signaler un bug pour l'utilisateur: les exceptions. Peut-être que cette idée a été empruntée à partir de php...
- oui, j'ai écrit un code qui dépend de ce comportement. Malheureusement je ne me souviens pas le code exact donc je ne peux pas vous dire pourquoi. Probablement eu à faire avec des sous-chaînes d'obtenir une chaîne vide peut être exactement ce que vous voulez à la fois.
- Je pense que sous-ensemble n'est pas tout à fait droit. "Intersection" serait plus correct, et selon que l'idiome de ce comportement fait beaucoup de sens. J'ai utilisé fréquemment, dans le cas où je veux effectuer une itération sur une sous-suite qui peut ou ne peut pas exister. Si la liste vide est retourné, le bloc n'a pas l'exécuter du tout. Cela permet d'économiser au moins un et souvent deux ou trois explicite si les déclarations, et évite la surcharge de la gestion des exceptions dans les boucles serrées.
Vous devez vous connecter pour publier un commentaire.
Vous avez raison!
'example'[3:4]
et'example'[3]
sont fondamentalement différents, et de découpage à l'extérieur des limites d'une séquence (au moins pour built-ins) ne cause pas une erreur.Il peut être surprenant au premier abord, mais il a un sens quand vous pensez à ce sujet. L'indexation retourne d'un seul élément, mais le tranchage renvoie une sous-suite d'articles. Ainsi, lorsque vous essayez d'index d'un inexistante valeur, il n'y a rien à y retourner. Mais quand vous la coupez une séquence à l'extérieur des limites du terrain, vous pouvez toujours retourner une séquence vide.
Partie de ce que la confusion est ici que les chaînes se comporter un peu différemment à partir de listes. Regardez ce qui se passe quand vous faites la même chose pour une liste:
Ici, la différence est évidente. Dans le cas de chaînes de caractères, les résultats semblent être identiques, car en Python, il n'y a pas une telle chose comme un caractère individuel à l'extérieur d'une chaîne. Un seul personnage est à seulement 1 chaîne de caractères.
(Pour la sémantique exacte de découpage en dehors de la plage d'une séquence, voir mgilson réponse.)
None
au lieu de erroring arrière - c'est l'habitude Python convention lorsque vous n'avez rien à y retourner.None
dans ce cas, il serait plus difficile de dire entre un dehors des limites d'un index et d'uneNone
valeur à l'intérieur d'une liste. Mais même si il y avait une solution pour que, il est clair pour moi que la restitution d'une séquence vide est la bonne chose à faire quand un hors-limites des tranches. C'est analogue à l'exécution de l'union de deux ensembles disjoints.None
valeurs dans une liste.x = [1, 2, 3]; x[100:105] = [4]
x = [1, 2, 3, 4, 5]; x[1:4] = [-1]; x == [1, -1, 5]
semble raisonnable. "Remplacer la partie sélectionnée de la liste avec cette nouvelle liste," il semble dire. La question est donc, pourquoi nex[100:105]
sélectionnez la liste vide à la fin dex
. Et je pense que la réponse doit être qu'il n'est pas vraiment un moins surprenant option. L'extension de la liste avec un rembourrage? Très surprenant! Pas d'erreur à la lecture mais erreur pour l'écriture? Quelque peu surprenant. L'ajout de la valeur? Juste un peu surprenant.None
dans une liste d'argument ne tient pas. Il y a une nette différence entreNone
et[None]
. Je n'ai toujours pas d'accord avec votre réponse, cependant.Pour le bien de l'ajout d'une réponse que les points d'un solide dans la section la documentation:
Donné une tranche d'expression comme
s[i:j:k]
,si vous écrivez
s[999:9999]
, python est de retours[len(s):len(s)]
depuislen(s) < 999
et votre démarche est positive (1
-- valeur par défaut).k
est positif,i
etj
sont également augmenté de-len(s)
quand ils le sont moins? par exemple,s = 'bac'; s[-100:2] == s[-len(s):2]
k
est positif, Python échellei
etj
afin qu'elles cadrent avec les limites de la séquence. Dans votre exemple,s[-100:2] == s[0:2]
(== s[-len(s):2]
, par la voie). De même,s[-100:100] == s[0:2]
.Découpage n'est pas de limites contrôlées par les types intégrés. Et bien que vos deux exemples semblent avoir le même résultat, ils fonctionnent différemment; essayez-les avec une liste à la place.