Pourquoi les itérateurs ne peuvent-ils pas être itérés plusieurs fois ? Une exploration et une solution complètes
Considérez le code suivant :
def test(data): for row in data: print("first loop") for row in data: print("second loop")
Lorsque les données sont un itérateur, tel qu'un itérateur de liste ou une expression génératrice, une itération deux fois dessus produit des résultats inattendus. :
>>> test(iter([1, 2])) first loop first loop >>> test((_ for _ in [1, 2])) first loop first loop
Ces exemples impriment la « première boucle » plusieurs fois, mais la « deuxième boucle » n'est jamais imprimée. Ce comportement soulève la question : pourquoi l’itération fonctionne-t-elle la première fois mais pas la seconde ? Et comment pouvons-nous remédier à cette limitation ?
Comprendre les itérateurs et la consommation
Un itérateur est un objet qui génère une valeur à la fois. Lors de l'itération, les itérateurs sont consommés, ce qui signifie qu'une fois parcourus, ils ne peuvent plus être itérés. Il en va de même pour les générateurs, les objets fichier et de nombreux autres objets itérables.
Ce comportement de consommation est illustré dans l'extrait de code suivant :
data = [1, 2, 3] it = iter(data) next(it) # => 1 next(it) # => 2 next(it) # => 3 next(it) # => StopIteration
Lorsque l'itérateur est consommé, il augmente une exception StopIteration lorsqu'il n'y a plus d'éléments à céder. Dans le contexte d'une boucle for, cette exception entraîne la fin de la boucle la première fois.
Solutions de contournement et approches alternatives
Si vous devez parcourir les mêmes données plusieurs fois, plusieurs solutions de contournement sont disponibles :
1. Créer une liste :
Vous pouvez stocker les éléments de l'itérateur dans une liste, qui peut ensuite être itérée autant de fois que vous le souhaitez :
data = list(it)
2 . Utilisez tee() pour les itérateurs indépendants :
Si votre itérateur traite un grand nombre d'éléments, la création d'une liste peut être inefficace. La fonction itertools.tee() permet de créer plusieurs itérateurs indépendants à partir d'une seule source :
import itertools it1, it2 = itertools.tee(data, 2) # create as many as needed
Chacun de ces itérateurs peut être parcouru séparément sans affecter les autres.
3. Convertir en séquence :
Certains itérateurs, tels que les ensembles, peuvent être convertis en séquences à l'aide de fonctions telles que list() ou tuple(). Cette conversion crée un nouvel objet qui peut être itéré plusieurs fois :
data = list(sorted(my_set))
En comprenant le comportement de consommation des itérateurs et en mettant en œuvre des solutions de contournement appropriées, vous pouvez profiter des avantages des objets itérables tout en vous assurant de disposer des données dont vous avez besoin. besoin de plusieurs itérations.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!