Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Python

Itérateurs Python

Itérateurs Python

Les itérateurs sont des objets sur lesquels on peut itérer. Dans ce didacticiel, vous apprendrez comment fonctionne l'itérateur et comment vous pouvez créer votre propre itérateur à l'aide des méthodes __iter__ et __next__.

Vidéo :Itérateurs Python

Itérateurs en Python

Les itérateurs sont partout en Python. Ils sont élégamment implémentés dans for boucles, compréhensions, générateurs etc. mais sont cachés à la vue de tous.

Iterator en Python est simplement un objet sur lequel on peut itérer. Un objet qui renverra des données, un élément à la fois.

Techniquement parlant, un objet itérateur Python doit implémenter deux méthodes spéciales, __iter__() et __next__() , collectivement appelés le protocole itérateur .

Un objet est dit itérable si nous pouvons en obtenir un itérateur. La plupart des conteneurs intégrés à Python tels que :liste, tuple, chaîne, etc. sont itérables.

Le iter() fonction (qui à son tour appelle la fonction __iter__() méthode) renvoie un itérateur à partir d'eux.

Itérer à travers un itérateur

Nous utilisons le next() fonction pour parcourir manuellement tous les éléments d'un itérateur. Lorsque nous arrivons à la fin et qu'il n'y a plus de données à renvoyer, cela lèvera le StopIteration Exception. Voici un exemple.

# define a list
my_list = [4, 7, 0, 3]

# get an iterator using iter()
my_iter = iter(my_list)

# iterate through it using next()

# Output: 4
print(next(my_iter))

# Output: 7
print(next(my_iter))

# next(obj) is same as obj.__next__()

# Output: 0
print(my_iter.__next__())

# Output: 3
print(my_iter.__next__())

# This will raise error, no items left
next(my_iter)

Sortie

4
7
0
3
Traceback (most recent call last):
  File "<string>", line 24, in <module>
    next(my_iter)
StopIteration

Une manière plus élégante d'itérer automatiquement consiste à utiliser la boucle for. En utilisant cela, nous pouvons parcourir n'importe quel objet pouvant renvoyer un itérateur, par exemple une liste, une chaîne, un fichier, etc.

>>> for element in my_list:
...     print(element)
...     
4
7
0
3

Fonctionnement de la boucle for pour les itérateurs

Comme nous le voyons dans l'exemple ci-dessus, le for loop a pu parcourir automatiquement la liste.

En fait le for loop peut itérer sur n'importe quel itérable. Examinons de plus près comment le for boucle est en fait implémentée en Python.

for element in iterable:
    # do something with element

Est en fait implémenté comme.

# create an iterator object from that iterable
iter_obj = iter(iterable)

# infinite loop
while True:
    try:
        # get the next item
        element = next(iter_obj)
        # do something with element
    except StopIteration:
        # if StopIteration is raised, break from loop
        break

Donc en interne, le for boucle crée un objet itérateur, iter_obj en appelant le iter() sur l'itérable.

Ironiquement, ce for est en fait une boucle while infinie.

À l'intérieur de la boucle, il appelle next() pour obtenir l'élément suivant et exécute le corps du for boucle avec cette valeur. Une fois tous les éléments épuisés, StopIteration est soulevé qui est pris à l'intérieur et la boucle se termine. Notez que tout autre type d'exception passera.

Construire des itérateurs personnalisés

Construire un itérateur à partir de zéro est facile en Python. Il suffit d'implémenter le __iter__() et le __next__() méthodes.

Le __iter__() renvoie l'objet itérateur lui-même. Si nécessaire, une initialisation peut être effectuée.

Le __next__() La méthode doit retourner l'élément suivant dans la séquence. En atteignant la fin, et dans les appels suivants, il doit lever StopIteration .

Ici, nous montrons un exemple qui nous donnera la prochaine puissance de 2 à chaque itération. L'exposant de puissance commence à partir de zéro jusqu'à un nombre défini par l'utilisateur.

Si vous n'avez aucune idée de la programmation orientée objet, visitez la programmation orientée objet Python.

class PowTwo:
    """Class to implement an iterator
    of powers of two"""

    def __init__(self, max=0):
        self.max = max

    def __iter__(self):
        self.n = 0
        return self

    def __next__(self):
        if self.n <= self.max:
            result = 2 ** self.n
            self.n += 1
            return result
        else:
            raise StopIteration


# create an object
numbers = PowTwo(3)

# create an iterable from the object
i = iter(numbers)

# Using next to get to the next iterator element
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))

Sortie

1
2
4
8
Traceback (most recent call last):
  File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in <module>
    print(next(i))
  File "<string>", line 18, in __next__
    raise StopIteration
StopIteration

On peut aussi utiliser un for boucle pour itérer sur notre classe d'itérateur.

>>> for i in PowTwo(5):
...     print(i)
...     
1
2
4
8
16
32

Itérateurs Python Infinis

Il n'est pas nécessaire que l'élément d'un objet itérateur soit épuisé. Il peut y avoir des itérateurs infinis (qui ne finissent jamais). Nous devons être prudents lors de la manipulation de tels itérateurs.

Voici un exemple simple pour démontrer les itérateurs infinis.

La fonction intégrée iter() peut être appelé avec deux arguments où le premier argument doit être un objet appelable (fonction) et le second est la sentinelle. L'itérateur appelle cette fonction jusqu'à ce que la valeur renvoyée soit égale à la sentinelle.

>>> int()
0

>>> inf = iter(int,1)
>>> next(inf)
0
>>> next(inf)
0

Nous pouvons voir que le int() fonction renvoie toujours 0. Donc, en le passant comme iter(int,1) renverra un itérateur qui appelle int() jusqu'à ce que la valeur renvoyée soit égale à 1. Cela n'arrive jamais et nous obtenons un itérateur infini.

Nous pouvons également construire nos propres itérateurs infinis. L'itérateur suivant retournera, théoriquement, tous les nombres impairs.

class InfIter:
    """Infinite iterator to return all
        odd numbers"""

    def __iter__(self):
        self.num = 1
        return self

    def __next__(self):
        num = self.num
        self.num += 2
        return num

Un exemple d'exécution serait le suivant.

>>> a = iter(InfIter())
>>> next(a)
1
>>> next(a)
3
>>> next(a)
5
>>> next(a)
7

Et ainsi de suite...

Veillez à inclure une condition de fin lors de l'itération sur ces types d'itérateurs infinis.

L'avantage d'utiliser des itérateurs est qu'ils économisent des ressources. Comme indiqué ci-dessus, nous pourrions obtenir tous les nombres impairs sans stocker le système de nombres entier en mémoire. Nous pouvons avoir des éléments infinis (théoriquement) dans une mémoire finie.

Il existe un moyen plus simple de créer des itérateurs en Python. Pour en savoir plus, consultez :Générateurs Python utilisant le rendement.


Python

  1. Types de données Python
  2. Opérateurs Python
  3. Instruction de passe Python
  4. Arguments de la fonction Python
  5. Dictionnaire Python
  6. Fermetures Python
  7. Date-heure Python
  8. Sommeil Python()
  9. Python - Présentation