← Retourner à la liste des articles
Image blog
Auteur

Par Maxime Jumelle

CTO & Co-Founder

Publié le 20 nov. 2020

Catégorie Machine Learning

Les itérateurs sous Python

Très souvent, nous avons besoin d'utiliser des boucles for pour itérer sur des listes à une ou plusieurs dimensions sous Python. Lorsque l'on débute, nous sommes tenté d'utiliser les mêmes façon d'itérer qu'en langage C, où l'on va définir une variable i qui indique la position du i-ème élément que l'on itère.

Mais le langage Python nous offre bien de plus de fonctionnalités concernant les itérations avec les itérateurs, qui vont nous permettre d'itérer sur des listes ou des objets de collection avec beaucoup de dextérité.

Les itérateurs natifs

Dans la plupart des cas, les itérateurs présents par défaut sous Python (aussi appelés built-in functions) vont résoudre notre problème.

L'itérateur enumerate

Considérons la liste suivante l1.

l1 = ['a', 'b', 'c', 'd', 'e']

Une simple boucle for va nous permettre d'itérer sur chaque élément de la liste l1.


À lire aussi : découvrez notre formation MLOps


for elem in l1:
  print(elem)

Si maintenant, on souhaite itérer sur chaque élément tout en connaissant la position de l'élément itéré de la liste, nous pourrions itérer simplement sur les indices des éléments de la liste l1.

for i in range(len(l1)):
  print(l1[i])

Mais cette écriture nécessite à la fois de créer un range, et est également moins lisible que dans le code précédent.

La fonction enumerate va justement combiner ces deux fonctionnalités : nous allons à la fois itérer sur les éléments de la liste, mais également sur leurs positions.

for i, elem in enumerate(l1):
  # Position i de l'élement elem de la liste l1
  print(i, ":", elem)

L'itérateur zip

Un autre itérateur à connaître est l'itérateur zip. Supposons que nous ayons deux listes, l1 et l2 de même taille. Si l'on souhaite itérer sur chaque élément de l1 et l2 en même temps, c'est-à-dire à la position i pour les deux listes, nous pourrions utiliser le code suivant.

l1 = [1, 2, 3, 4, 5]
l2 = ['a', 'b', 'c', 'd', 'e']

for i in range(len(l1)):
  print(l1[i], ":", l2[i])

L'itérateur zip va nous économiser du code puisque l'on va directement itérer sur les éléments côte-à-côte de chacune des deux listes.

for elem1, elem2 in zip(l1, l2):
  print(elem1, ":", elem2)

C'est donc beaucoup plus lisible avec la fonction zip.

ℹ️ Par ailleurs, la fonction

zip
peut itérer sur plus de deux listes. Dans l'exemple suivant, elle est appliquée sur trois listes, où le même principe d'itération côte-à-côte va être utilisé.

l1 = [1, 2, 3, 4, 5]
l2 = ['a', 'b', 'c', 'd', 'e']
l3 = [2, 5, 4, 7, 1]

for a, b, c in zip(l1, l2, l3):
  print(a, b, c)

Créer son propre itérateur

Nous allons pouvoir créer notre propre itérateur ! En particulier, nous devons définir deux fonctions pour définir un itérateur.

  • Le démarrage de l'itération avec la fonction __iter__.
  • Le comportement de chaque itération avec la fonction __next__.

Prenons un cas simple où l'objet Personnes permet de stocker les informations de plusieurs personnes.

Chaque élément de Personnes est un dictionnaire Python qui contient plusieurs champs (nom, prénom, âge, etc). Or, en itération sur Personnes, nous aimerions uniquement récupérer le champ name et non l'intégralité du dictionnaire.

En itérant sur les éléments de Personnes, nous allons donc renvoyer uniquement une chaîne de caractères qui correspond au nom de la personne concernée.

class Personnes():
  index = 0

  def __init__(self, personnes=[]):
    # On initialise notre liste personnes (qui peut être vide)
    self.personnes = personnes

  def __iter__(self):
    # Fonction exécutée lorsque l'on exécute une itération sur cet object (dans un for par exemple)
    self.index = 0  # On commence au début de la liste (index = 0)
    return self

  def __next__(self):
    # Fonction exécutée à chaque itération
    if self.index >= len(self.personnes):  # Si on a parcouru la liste
      raise StopIteration  # Cela stoppe l'exécution
    else:
      x = self.personnes[self.index]['name']  # Sinon on récupère le nom de la i-ème personne
      self.index += 1
      return x

Il est maintenant possible d'initialiser l'objet Personnes avec une liste par défaut qui contient déjà 4 éléments.


À lire aussi : découvrez notre formation MLOps


pers = Personnes([
  {'name': "A", 'city': "Paris"},
  {'name': "B", 'city': "Milan"},
  {'name': "C", 'city': "New-York"},
  {'name': "D", 'city': "London"}
])

# On itère sur l'objet Personnes
for p in pers:
  print(p)

En itérant sur la variable pers, la variable p contient uniquement le champ name, conformément à ce qui est décrit dans la fonction __next__.

Avec toutes ces fonctions très utiles, nous pouvons profiter pleinement de la puissance de Python sur la manipulation des objets et des variables.

Vous souhaitez vous former au MLOps ?

Articles similaires

Blog

20 sept. 2022

Machine Learning

Hugging Face est une startup française qui s'est fait connaître grâce à l'infrastructure NLP qu'ils ont développée. Aujourd'hui, elle est sur le point de révolutionner le domaine du Machine Learning et traitement automatique du langage naturel. Dans cet article, nous allons présenter Hugging Face et détailler les taches de base que cette librairie permet de réaliser. Nous allons également énumérer ses avantages et ses alternatifs.

Nada Belaidi

Équipe Blent

Data Scientist

Lire l'article

Blog

12 juil. 2022

Machine Learning

spaCy est une bibliothèque open-source pour le traitement avancé du langage naturel. Elle est conçue spécifiquement pour une utilisation en production et permet de construire des applications qui traitent et comprennent de grands volumes de texte.

Nada Belaidi

Équipe Blent

Data Scientist

Lire l'article

Blog

4 juil. 2022

Machine Learning

Un auto-encodeur est une structure de réseaux neuronaux profonds qui s'entraîne pour réduire la quantité de données nécessaires pour représenter une donnée d'entrée. Ils sont couramment utilisés en apprentissage automatique pour effectuer des tâches de compression de données, d'apprentissage de représentations et de détection de motifs.

Nada Belaidi

Équipe Blent

Data Scientist

Lire l'article