Pourquoi ne range(start, end) de ne pas inclure fin?
>>> range(1,11)
vous donne
[1,2,3,4,5,6,7,8,9,10]
Pourquoi ne pas 1-11?
Ont-ils tout simplement de décider de le faire comme ça au hasard, ou faut-il avoir une certaine valeur, je ne suis pas le voir?
range(len(s))
- lire Dijkstra, ewd831
- Fondamentalement, vous faites le choix d'un ensemble de tout-en-un de bugs pour l'autre. Un ensemble sont plus susceptibles de causer à vos boucles de mettre un terme plus tôt, l'autre est susceptible de provoquer une Exception (ou de débordement de la mémoire tampon dans d'autres langues). Une fois que vous avez écrit un tas de code, vous verrez que le choix de comportement
range()
a un sens beaucoup plus souvent - Lien de Dijkstra, ewd831: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
- Que Djikstra l'article est souvent cité dans ce sujet, mais ne prévoit rien de valeur, ici, les gens de l'utiliser comme un appel à l'autorité. La seule pseudo-raison qu'il donne pour l'OP de la question est qu'il arrive à sentir que l'inclusion de la limite supérieure devient "naturelle" et "laid" dans le cas particulier où la séquence dans le vide qui est totalement subjective de la position et facilement soutenu contre, il n'apporte pas beaucoup à la table. L ' "expérience" Mesa n'est pas de beaucoup de valeur, que ce soit sans connaître leurs contraintes particulières ou des méthodes d'évaluation.
- Dijkstras argument est que la convention
a < i <= b
est le seul pour lequela
etb
jamais besoin de quitter l'ensemble des nombres naturels, aussi longtemps que la gamme dei
est soit vide ou dans l'ensemble des nombres naturels. Bien que la plupart des cosmétiques argument, je pense qu'il est parfaitement valide. - Mais même si les cosmétiques argument est valide, n'est-ce pas Python approche introduire un nouveau problème de lisibilité? En commun-utilisation de l'anglais, le terme "gamme" implique que quelque chose va de quelque chose à quelque chose-comme un intervalle. Que len(list(range(1,2))) renvoie 1 et len(list(range(2))) renvoie 2 est quelque chose que vous avez vraiment à apprendre à digérer.
- Un autre bizarre Python convention emprunté. 😛 je préfère simuler intuition naturelle et de ne pas faire quelque chose comme janvier[0], février[1], etc.
- Ce serait bien si la fourchette() a offert une option pour l'inclusion: la limite supérieure. Je suis très bien avec range() exclusif par défaut, mais il existe des situations où inclusive rend la syntaxe plus lisible.
Vous devez vous connecter pour publier un commentaire.
Parce qu'il est plus courant d'appel
range(0, 10)
qui renvoie[0,1,2,3,4,5,6,7,8,9]
qui contient 10 éléments qui équivaut àlen(range(0, 10))
. Rappelez-vous que les programmeurs préfèrent 0 basée sur l'indexation.Aussi, considérons le code suivant extrait de:
Pourriez-vous voir que si
range()
est allé jusqu'à exactementlen(li)
que ce serait problématique? Le programmeur devra explicitement soustraire 1. Cela suit également la tendance commune de programmeurs préférantfor(int i = 0; i < 10; i++)
surfor(int i = 0; i <= 9; i++)
.Si vous appelez de la gamme avec un début de 1 fréquemment, vous pouvez définir votre propre fonction:
range(start, count)
?range(10)
est équivalent àrange(0, 10)
.range1
ne fonctionnera pas avec les plages qui ont une autre étape de la taille de1
.range(0, 10, 2)
est[0, 2, 4, 6, 8]
qui, évidemment, n'ont pas de 10 éléments. Je suppose qu'il auraitend / step
éléments, arrondissement à la baisse des cours.range1 = lambda start,end,step: range(start,end+1,step) for i in range(1,26): print(i) for i in range1(1,25,3): print(i)
for i in range(len(li)):
est plutôt un antipattern. On devrait utiliserenumerate
.Exclusive plages ont certains avantages:
Pour une chose chaque élément dans
range(0,n)
est un index valide pour les listes de longueurn
.Aussi
range(0,n)
a une longueur den
, pasn+1
qui est inclusif de la plage.Bien qu'il y a certains algorithmique ici des explications, je pense qu'il peut aider à ajouter un peu simple de la "vraie vie" raisonnement pour expliquer pourquoi cela fonctionne de cette façon que j'ai trouvé utile lors de l'introduction de l'objet pour les jeunes nouveaux arrivants:
Avec quelque chose comme 'range(1,10)' confusion peut naître de penser que la paire de paramètres représentant le début et la fin".
Il est réellement démarrer et "stop".
Maintenant, si il ont été la "fin" de la valeur alors, oui, vous pourriez vous attendre que nombre pourraient être inclus dans la dernière entrée dans la séquence. Mais ce n'est pas la "fin".
D'autres appellent à tort que le paramètre "nombre" parce que si vous n'utilisez jamais de répartition(n)' alors il n'a, bien sûr, itérer 'n' fois. Cette logique s'effondre lorsque vous ajoutez le paramètre de démarrage.
De sorte que le point clé est de se rappeler de son nom: "arrêter".
Cela signifie que c'est le point qui, lorsqu'il est atteint, l'itération s'arrête immédiatement. Pas après ce point.
Ainsi, alors que "démarrer" constitue, en effet, la première valeur qui doit être inclus, en arrivant à "arrêter la" valeur "pauses" plutôt que de continuer à traiter des "ainsi que une' avant de s'arrêter.
Une analogie que j'ai utilisé pour expliquer cela aux jeunes, c'est que, ironiquement, c'est mieux comportés que les enfants! Il ne s'arrête pas après il se devait - il s'arrête immédiatement sans finir ce qu'il était en train de faire. (Ils arriver à ça 😉 )
Une autre analogie - quand vous conduisez une voiture, vous n'avez pas passer un stop/rendement/'céder' signe et à la fin, avec elle, assis quelque part à côté, ou derrière votre voiture. Techniquement, vous n'avez pas encore atteint quand vous le faites arrêter. Il n'est pas inclus dans les " choses que vous avez passé sur votre voyage.
J'espère que certains qui aide à expliquer à Pythonitos/Pythonitas!
Il fonctionne bien en combinaison avec de base zéro de l'indexation et de
len()
. Par exemple, si vous avez 10 éléments dans une listex
, elles sont numérotées de 0 à 9.range(len(x))
vous donne 0-9.Bien sûr, les gens vont vous dire que c'est plus Pythonic faire
for item in x
oufor index, item in enumerate(x)
plutôt quefor i in range(len(x))
.Découpage fonctionne de cette façon:
foo[1:4]
est articles 1 à 3 defoo
(en gardant à l'esprit que le point 1 est en fait le deuxième élément en raison de la non-indexation). Pour des raisons de cohérence, elles doivent fonctionner de la même façon.Je pense que: "le premier numéro que vous voulez, suivie par le premier numéro que vous ne pas voulez." Si vous voulez 1-10, le premier numéro que vous ne voulez pas est 11, il est donc
range(1, 11)
.Si ça devient lourd dans une application particulière, il est assez facile d'écrire une petite fonction d'assistance qui ajoute 1 à la fin de l'index et des appels
range()
.w = 'abc'; w[:] == w[0:len(w)]; w[:-1] == w[0:len(w)-1];
def full_range(start,stop): return range(start,stop+1) ## helper function
for index, item in enumerate(x)
pour éviter la confusionIl est également utile pour le fractionnement des plages;
range(a,b)
peut être divisé enrange(a, x)
etrange(x, b)
, tandis que la plage inclusive vous écrirex-1
oux+1
. Alors que vous avez rarement besoin de diviser les plages, vous ne ont tendance à diviser les listes assez souvent, qui est l'une des raisons pour trancher une listel[a:b]
comprend l'un-ème élément, mais pas le b-th. Puisrange
ayant la même propriété la rend bien cohérent.La longueur de la gamme est la valeur la plus élevée, moins la valeur du bas.
C'est très semblable à quelque chose comme:
dans un C-langage de style.
Aussi comme le Rubis est la gamme:
Cependant, Ruby reconnaît que de nombreuses fois, vous aurez envie d'inclure la valeur terminale et propose la syntaxe alternative:
1..10
vs1...10
être difficile de distinguer entre le moment de la lecture de code!..
est venu en premier et n'a mathématiquement correcte gamme exclusive. Mais ensuite, ils ont décidé "nous avons besoin d'une large gamme parce que le bonheur de programmation seraient touchés par faire1..n+1
, ils ont donc décidé d'ajouter sur un.
car il est si petit et ne prendra pas trop de place, donc pas de prendre le chemin du programmeur bonheur. (C'est une langue-dans-joue post)Examiner le code
L'idée est que vous obtenez une liste de longueur
y-x
, que vous pouvez (comme vous le voyez ci-dessus) itérer sur.Lire sur le python docs de gamme - ils envisager pour la boucle d'itération le principal cas d'utilisation.
Essentiellement en python
range(n)
itèren
fois, ce qui est de l'exclusivité de la nature, c'est pourquoi il ne donne pas la dernière valeur lorsqu'il est en cours d'impression, nous pouvons créer une fonction qui donnela valeur forfaitaire cela signifie qu'il sera également imprimer la dernière valeur mentionnée dans la gamme.
C'est juste plus pratique de la raison, dans de nombreux cas.
Fondamentalement, on pourrait penser à une plage comme un intervalle entre
start
etend
. Sistart <= end
, la longueur de l'intervalle entre eux estend - start
. Silen
a effectivement été défini comme la longueur, vous auriez:Cependant, nous comptons les entiers compris dans l'intervalle au lieu de mesurer la longueur de l'intervalle. Pour garder les biens ci-dessus vrai, nous devons inclure l'un des points de terminaison et d'exclure les autres.
L'ajout de la
step
paramètre est comme l'introduction d'une unité de longueur. Dans ce cas, vous vous attendezpour la longueur. Pour obtenir le nombre, il vous suffit d'utiliser division entière.