Besoin de comprendre la différence entre range(0,2)
et list(range(0,2))
, en utilisant python2.7
Les deux renvoient une liste alors quelle est exactement la différence?
En Python 3.x,
range(0,3)
renvoie une classe d'objets immuables immuables qui vous permettent de les parcourir, ils ne produisent pas de listes et ne stockent pas tous les éléments de la plage en mémoire. Ils produisent plutôt les éléments à la volée (car vous les parcourez ), alors que list(range(0,3))
produit une liste (en itérant sur tous les éléments et en ajoutant à la liste en interne).
Exemple -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
Idéalement, si vous souhaitez uniquement effectuer une itération sur cette plage de valeurs, range(0,3)
sera plus rapide que (list(range(0,3))
car ce dernier a le temps de produire une liste avant que vous ne commenciez à l'itérer.
Dans Python 2.x, range(0,3)
génère une liste. Nous avions également une fonction xrange()
ayant le même comportement que la fonction range()
de Python 3.x (xrange a été renommé pour s’étendre dans Python 3.x).
Pour Python 3.5, à partir de documentation -
Les objets Range implémentent ABC collections.abc.Sequence et fournissent des fonctionnalités telles que des tests de confinement, la recherche d'index d'éléments, le découpage en tranches et la prise en charge des index négatifs.
Pour que vous puissiez faire des choses comme -
>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
Et toutes ces opérations sont des opérations à temps constant, comme le montre ce test -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
Les deux commandes renvoient la liste en Python2.x. Mais dans Python3.x, la plage est une séquence immuable et ne renvoie pas de liste. Il est utilisé pour les itérations et les boucles
En gros, la différence est que range(0, 2)
est une fonction génératrice et list(range(0, 2))
est une liste réelle.
Une fonction génératrice est utilisée dans les boucles. Par exemple, une fonction génératrice d'un fichier lira un très gros fichier ligne par ligne.
def gen():
for line in open("hugefile.csv", "r"):
yield line #Gives back the line every time it is read, but forgets that line after
for line in gen():
print(line)
Ceci imprimera chaque ligne sans surcharger le RAM de l'ordinateur car vous ne lisez qu'un par un dans les deux fonctions. Cependant, si nous faisons quelque chose comme
def readEntireFile():
return [line for line in open("hugefile.csv", "r")] #Python has lazy ways of making lists, this is the same as returning a list with all the lines in the file
for line in readEntireFile():
print(line)
La deuxième partie a le même aspect, mais ce n’est pas le cas. À l'origine, nous parcourions chaque ligne du fichier et passions à la ligne suivante une fois que nous en avions terminé. Ici, Python a une liste de TOUTES les lignes: /, imaginez faire cela avec un fichier de 10 Go! Votre code planterait.
Revenons maintenant à range () et list (range ())
Faire for x in range(0, 6):
nous fait passer au nombre suivant dans la plage et oublier complètement le précédent (Grammaire vis-à-vis).
Cependant, faire for x in list(range(0, 6)):
conserve la liste complète des nombres en mémoire et revient à faire
numlist = [x for x in range(6)]
for x in numlist:
print(x)
Lorsque vous avez besoin de la liste complète des données de votre code, utilisez la méthode list. Toutefois, lorsque vous n’avez besoin que d’une seule donnée à la fois (exemple le plus simple, copie d’un fichier par morceaux), utilisez une fonction de générateur pour économiser de l’espace. Vous pouvez copier chaque million de lignes d'un fichier en n'utilisant que 54 Mo (en supposant que vous n'avez pas de lignes extrêmement longues). Cependant, si nous avons un petit fichier de 2 Ko, nous pouvons simplement copier cette chose sans générateur. Cela ne vaut pas la peine et c'est plus lent dans ce cas.
En python3.x, la plage a son propre type
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>
Donc, si vous voulez utiliser range () dans une boucle for, tout va bien. Cependant, vous ne pouvez pas l'utiliser purely
comme objet de liste. Vous devez le convertir en liste pour le faire.
Exemple Python2:
>>> L = range(10)
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Exemple Python3:
>>> L = range(10)
>>> L[::-1]
range(9, -1, -1)