Les itérateurs en Python

L'itération est un concept fondamental en Python. Elle désigne l'action d'accéder séquentiellement à chaque élément d'un conteneur selon un ordre prédéfini, comme lors de l'utilisation d'une boucle for.

Objets itérables (Iterable)

Un objet itérable est un objet capable de produire un itérateur. En d'autres termes, c'est un objet qui peut fournir ses éléments un par un. Les types de collections intégrés tels que list, set, dict, tuple et str sont tous itérables. Cela signifie qu'ils peuvent être parcourus avec une boucle for.

  • Les objets itérables possèdent généralement une méthode __iter__ permettant de générer un itérateur

Caractéristiques des objets itérables :

  • On peut obtenir un itérateur via la fonction iter()
  • Ils sont compatibles avec les boucles for, grâce à leur interface d'itérateur
# Parcours d'une liste avec for
ma_liste = [1, 2, 3]
for element in ma_liste:
    print(element)

# Parcours d'un tuple avec for
t = (1, 2, 3)
for element in t:
    print(element)

# Parcours d'un ensemble avec for
s = {1, 2, 3, 4}
for element in s:
    print(element)

# Parcours d'un dictionnaire avec for
mon_dico = {'nom':'Jim', 'age':12}
for cle in mon_dico:
    print(cle)

Itérateurs (Iterator)

Un itérateur est un objet implémentant les méthodes __iter__() et __next__(). La première retourne l'itérateur lui-même, la seconde renvoie l'élément suivant de la séquence.

Les itérateurs sont des objets itérables particuliesr :

  • __next__ : Accède aux éléments de l'itérateur
  • Démarre par le premier élément et se termine au dernier. Une tentative d'accès supplémentaire déclenche l'exception StopIteration. Les éléments sont consommés après accès.

Caractéristiques des itérateurs :

  • Objet mémorisant sa position d'itération
  • Parcours linéaire du début à la fin, sans possibilité de recul
  • L'élément suivant peut être récupéré manuellement avec next(), ce qui déclenche StopIteration à la fin
class IterateurPersonnalise:
    def __init__(self, elements):
        self.elements = elements
        self.position = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.position >= len(self.elements):
            raise StopIteration
        resultat = self.elements[self.position]
        self.position += 1
        return resultat

# Utilisation de l'itérateur
mon_iterateur = IterateurPersonnalise([1, 2, 3])
for valeur in mon_iterateur:
    print(valeur)

it1 = ma_liste.__iter__()
it1

it1.__next__()

it1.__next__()

it1.__next__()

# Tentative d'accès au-delà de la fin déclenche StopIteration
it1.__next__()

Synthèse sur les itérateurs et objets itérables :

  • Tous les itérateurs sont itérables, mais l'inverse n'est pas vrai
  • Les objets itérables fournissent un itérateur, tandis que les itérateurs permettent l'itération
# Utilisation d'une boucle for avec itérateur
class IterateurNumerique:
    def __init__(self, valeurs):
        self.valeurs = valeurs
        self.compteur = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.compteur >= len(self.valeurs):
            raise StopIteration
        resultat = self.valeurs[self.compteur]
        self.compteur += 1
        return resultat

# Instanciation et itération
iterateur = IterateurNumerique([1, 2, 3, 4, 5])
for numero in iterateur:
    print(numero)

# Utilisation d'une boucle while
iterateur = IterateurNumerique([1, 2, 3, 4, 5, 6])
it = iter(iterateur)
while True:
    try:
        print(next(it))
    except StopIteration:
        break

Avantages des itérateurs

  • Efficacité mémoire : Calcul des valeurs sur demande, sans stockage complet en mémoire
  • Calcul paresseux : Génération progressive des éléments, utile pour les grands ensembles ou flux infinis
  • Interface unifiée : Permet d'itérer sur n'importe quelle structure sans connaître sa nature interne
class IterateurFibonacci:
def __init__(self):
self.premier = 0
self.second = 1

def __iter__(self):
return self

def __next__(self):
resultat = self.premier
self.premier, self.second = self.second, self.premier + self.second
return resultat

# Génération d'une suite infinie
fib_iter = IterateurFibonacci()

# Affichage des 10 premiers nombres
for i, nombre in enumerate(fib_iter):
if i >= 10:
break
print(nombre)

Étiquettes: Python itérateurs Programmation orientée objet

Publié le 10 septembre à 05h11