Quand est-il préférable d'utiliser zip
au lieu de itertools.izip
?
Vous avez raison. J'ai commencé avec de bonnes intentions et puis je suis tombé dans des trucs théoriques...
Quand est-il préférable d'utiliser zip
au lieu de itertools.izip
?
zip
calcule toute la liste en une seule fois, izip
ne calcule les éléments que sur demande.
Une différence importante est que 'zip' renvoie une liste réelle, 'izip' renvoie un 'objet izip', qui n'est pas une liste et ne supporte pas les fonctionnalités spécifiques aux listes (comme l'indexation) :
>>> l1 = [1, 2, 3, 4, 5, 6]
>>> l2 = [2, 3, 4, 5, 6, 7]
>>> z = zip(l1, l2)
>>> iz = izip(l1, l2)
>>> isinstance(zip(l1, l2), list)
True
>>> isinstance(izip(l1, l2), list)
False
>>> z[::2] #Get odd places
[(1, 2), (3, 4), (5, 6)]
>>> iz[::2] #Same with izip
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'itertools.izip' object is unsubscriptable
Ainsi, si vous avez besoin d'une liste (et non d'un objet ressemblant à une liste), utilisez simplement 'zip'.
En outre, "izip" peut être utile pour économiser de la mémoire ou des cycles.
Par exemple, le code suivant peut se terminer après quelques cycles, il n'est donc pas nécessaire de calculer tous les éléments de la liste combinée :
lst_a = ... #list with very large number of items
lst_b = ... #list with very large number of items
#At each cycle, the next couple is provided
for a, b in izip(lst_a, lst_b):
if a == b:
break
print a
en utilisant zip
aurait calculé tous (a, b)
couples avant d'entrer dans le cycle.
En outre, si lst_a
et lst_b
sont très grandes (par exemple, des millions d'enregistrements), zip(a, b)
va construire une troisième liste avec un double espace.
Mais si vous avez de petites listes, peut-être zip
est plus rapide.
Lorsque vous savez que vous voudrez la liste complète des éléments construits (par exemple, pour la transmettre à une fonction qui modifierait cette liste en cours de route). Ou lorsque vous voulez forcer les arguments que vous passez à la fonction zip()
pour être complètement évalué à ce moment précis.
Ne serait-il pas préférable d'utiliser izip dans le premier cas car il est plus rapide puisqu'il réutilise le tuple et il n'y a pas de réelle raison de ne pas utiliser izip ?
@user1815201 : izip
ne fait que réutiliser le tuple
si le tuple
a été publié avant que l'itération suivante ne commence, donc il ne vous rapporte rien. Cela dit, toute perte est triviale aussi, donc je suis d'accord qu'il y a peu de raison de ne pas utiliser izip
exclusivement, en enveloppant avec list
si vous avez besoin d'un list
; vous pouvez en fait faire cela de la manière "correcte" en ajoutant from future_builtins import zip
au code Py2, ce qui rend simple zip
en izip
(préparation de la transition vers Py3).
La bibliothèque itertools fournit des "itérateurs" pour les fonctions Python courantes. D'après la documentation d'itertools, "Comme zip() sauf qu'il retourne un itérateur au lieu d'une liste". Le I dans izip() signifie "itérateur".
Les itérateurs Python sont une séquence "lazy loaded" qui permet d'économiser de la mémoire par rapport à une liste régulière en mémoire. Ainsi, vous utiliserez itertools.izip(a, b) lorsque les deux entrées a, b sont trop grandes pour être gardées en mémoire en une seule fois.
Recherchez les concepts Python liés au traitement séquentiel efficace :
"generators" & "yield"
"iterators"
"lazy loading"
Pas vraiment. C'est pourquoi j'ai tendance à préférer itertools.izip()
sauf lorsque les gains seraient purement statistiques.
Un cas où vous avez besoin d'une liste est celui où vous prévoyez d'accéder aux éléments du résultat par index ou avez besoin de trouver la longueur totale. lst = zip(lst_a, lst_b)
permet à lst[1]
ou len(lst)
. Cependant, pour ilst = itertools.izip(lst_a, lst_n)
vous échouerez en essayant de ilst[1]
ou len(ilst)
.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Une raison en faveur de
zip
trop évident, mais qui vaut quand même la peine d'être souligné, c'est queizip
renvoie uniterator
qui ne peut être parcouru qu'une seule fois, c'est-à-dire que dansii = izip(a,b) ; f(ii) ; g(ii)
ici une liste vide[]
est transmis àg
.11 votes
Pour votre information, la version de Python 3
zip
est la fonction de Python 2izip
. En général, Python 3 a modifié la plupart des fonctions pour utiliser des itérateurs, comme range, filter, les fonctions dict, etc