Je comprends comment des fonctions comme range()
et Zip()
peuvent être utilisées dans une boucle for. Cependant, je m'attendais à ce que range()
produise une liste, un peu comme seq
dans le shell unix. Si je lance le code suivant:
a=range(10)
print(a)
La sortie est range(10)
, suggérant que ce n'est pas une liste mais un type d'objet différent. Zip()
a un comportement similaire lors de l'impression, produisant quelque chose comme
<Zip object at "hexadecimal number">
Ma question est donc de savoir quels sont ces avantages, quels sont leurs avantages, et comment puis-je obtenir leurs résultats sous forme de listes sans les survoler?
Vous devez utiliser Python 3.
Dans Python 2, les objets Zip
et range
se sont comportés comme vous le suggérez, renvoyant des listes. Elles ont été remplacées par générateur - des objets semblables à ceux qui produisent les éléments à la demande plutôt que d’étendre une liste entière en mémoire, ce qui présente un avantage: une efficacité accrue dans leurs cas d’utilisation typiques (par exemple, une itération sur eux).
Les versions "paresseuses" existent également dans Python 2.x, mais elles portent des noms différents, c.-à-d. xrange
et itertools.izip
.
Pour récupérer toutes les sorties en même temps dans un objet de liste familier, vous pouvez simplement appeler list
pour itérer et consommer le contenu:
>>> list(range(3))
[0, 1, 2]
>>> list(Zip(range(3), 'abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
Dans Python 3.x., range
renvoie un objet de plage au lieu d'une liste comme dans Python De même, Zip
renvoie désormais un objet Zip au lieu d'une liste.
Pour obtenir ces objets sous forme de listes, mettez-les dans list
:
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> Zip('abc', 'abc')
<Zip object at 0x01DB7120>
>>> list(Zip('abc', 'abc'))
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>>
Bien que cela puisse sembler inutile au début, ce changement de comportement de range
et Zip
augmente en réalité l'efficacité. En effet, les objets Zip et Range produisent les éléments dont ils ont besoin au lieu de créer une liste pour les contenir tous en même temps. Cela permet de réduire la consommation de mémoire et d’accroître la vitesse de fonctionnement.
Range (xrange
in python 2. *) sont des objets séquences immuables , tandis que Zip (itertools.izip
_ respectivement) est un objet générateur . Pour créer une liste à partir d'un générateur ou d'une séquence, il suffit de la transcrire en liste. Par exemple:
>>> x = range(10)
>>> list(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Mais ils diffèrent dans la manière dont les éléments sont générés. Les générateurs normaux sont modifiables et affichent leur contenu s'ils sont itérés, alors que la plage est immuable, et ne le font pas:
>>> list(x) # x is a range-object
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # second cast to list, contents is the same
>>> y = Zip('abc', 'abc')
>>> list(y) # y is a generator
[('a', 'a'), ('b', 'b'), ('c', 'c')]
>>> list(y)
[] # second cast to list, content is empty!