Je crois comprendre que la range()
fonction, qui est en fait un type d'objet en Python 3 , génère son contenu à la volée, semblable à un générateur.
Cela étant le cas, je m'attendais à ce que la ligne suivante prenne un temps excessif, car pour déterminer si 1 quadrillion est dans la plage, il faudrait générer un quadrillion de valeurs:
1000000000000000 in range(1000000000000001)
De plus: il semble que peu importe le nombre de zéros que j'ajoute, le calcul prend plus ou moins le même temps (essentiellement instantané).
J'ai également essayé des choses comme ça, mais le calcul est encore presque instantané:
1000000000000000000000 in range(0,1000000000000000000001,10) # count by tens
Si j'essaie d'implémenter ma propre fonction de plage, le résultat n'est pas si agréable !!
def my_crappy_range(N):
i = 0
while i < N:
yield i
i += 1
return
Que fait l' range()
objet sous le capot qui le rend si rapide?
La réponse de Martijn Pieters a été choisie pour son exhaustivité, mais voir également la première réponse d'Abarnert pour une bonne discussion de ce que cela signifie pour range
être une séquence à part entière dans Python 3, et quelques informations / avertissements concernant l'incohérence potentielle pour __contains__
l'optimisation des fonctions dans les implémentations Python . L'autre réponse d'abarnert va plus en détail et fournit des liens pour ceux qui s'intéressent à l'histoire derrière l'optimisation dans Python 3 (et le manque d'optimisation de xrange
dans Python 2). Les réponses par poke et par wim fournissent le code source C pertinent et des explications pour ceux qui sont intéressés.
range
c'était un générateur?
xrange
identique à Python3range
?
xrange()
objets @Superbest n'ont pas de __contains__
méthode, donc la vérification des éléments doit parcourir tous les éléments. De plus , il y a peu d' autres changements dans range()
, comme il prend en charge le découpage (qui retourne à nouveau un range
objet) et maintenant aussi count
et index
méthodes pour le rendre compatible avec collections.Sequence
ABC.
bool
oulong
, avec d'autres types d'objets, cela deviendra fou. Essayez avec:100000000000000.0 in range(1000000000000001)