DéveloppeurWeb.Com
    DéveloppeurWeb.Com
    • Agile Zone
    • AI Zone
    • Cloud Zone
    • Database Zone
    • DevOps Zone
    • Integration Zone
    • Web Dev Zone
    DéveloppeurWeb.Com
    Home»Uncategorized»Implémentation des fonctions du générateur Python : un guide complet
    Uncategorized

    Implémentation des fonctions du générateur Python : un guide complet

    février 1, 2023
    Implémentation des fonctions du générateur Python : un guide complet
    Share
    Facebook Twitter Pinterest Reddit WhatsApp Email

    Avez-vous déjà rencontré des problèmes de mémoire en travaillant avec un très grand ensemble de données ou en travaillant avec une séquence infinie de données ? La conversion des objets en objets itérables aide ici, ce qui peut être facilement fait par les fonctions du générateur Python. Depuis la PEP 255, lorsque les générateurs ont été introduits pour la première fois, Python les a largement incorporés. Vous pouvez déclarer une fonction qui agit comme un itérateur en utilisant des fonctions génératrices de manière simple et efficace.

    Dans cet article, nous discuterons de ce que sont les objets itérateurs en Python, comment ils peuvent être déclarés à l’aide des fonctions et expressions du générateur Python, et pourquoi et où ils sont utilisés et préférés.

    Itérateurs en Python

    Un objet qui peut être itéré (souvent utilisé dans de nombreuses applications en boucle Python) est appelé itérateur. Un conteneur de données est abstrait pour se comporter comme un objet itérable en utilisant cette technique. Les objets itérables comme les chaînes, les listes et les dictionnaires sont des exemples très courants d’objets itérables en Python.

    Par exemple, une séquence de nombres premiers qui peut être itérée, comme un tableau ou une liste, est itérée lors de l’utilisation d’un pour la boucle: ([3, 5, 7, 11, …)].

    Un itérateur est défini par une classe qui suit le protocole de l’itérateur. Au sein de la classe, les deux méthodes __iter__ et __next__ sont recherchés par ce protocole.

    Passons en revue un exemple pour implémenter un objet itérable :

    class list_even:
    
        def __init__(self, max):
    
            self.n=2
    
            self.max=max
    
    
    
        def __iter__(self):
    
            return self
    
    
    
        def __next__(self):
    
            if self.n <= self.max:
    
                result = self.n
    
                self.n += 2
    
                return result
    
            else:
    
                raise StopIteration
    
    even_nos = list_even(15)
    
    print(next(even_nos))
    
    print(next(even_nos))
    
    print(next(even_nos))
    

    Ce qui donne cette sortie :

    Comme indiqué, pour qu’un objet soit un itérateur, il doit implémenter le __iter__ et __next__ les fonctions. Les __init__ La fonction initialise l’objet avec la valeur maximale possible. Les __iter__ La fonction renvoie l’objet itérateur lorsque l’objet est appelé, et la __next__ renvoie l’élément suivant dans la séquence et peut augmenter la StopIteration exception s’il n’y a pas de valeurs à retourner.

    Le processus illustré ci-dessus est clairement long et les générateurs viennent à la rescousse pour faire la même chose d’une manière assez simple.

    Note: Les itérateurs ne peuvent être itérés qu’une seule fois. Aucune valeur ne sera fournie si vous essayez d’itérer à nouveau. Il agira comme une liste vide. Cela ressort clairement du fait que, le next() la fonction augmente le nombre à chaque fois et il n’y a pas de retour dans la liste. Cela peut cependant être personnalisé.

    Nous pouvons également itérer sur cet objet, en utilisant un pour la boucle:

    even_nos = list_even(9)
    
    for number in list_even:
    
        print(number)

    Ce qui donne cette sortie :

    Fonctions du générateur

    Les fonctions génératrices nous permettent de déclarer des objets itérateurs de manière simple et plus efficace. Nous verrons comment cela est possible.

    Les fonctions du générateur se comportent et s’affichent comme des fonctions normales à une exception près. Au lieu de « renvoyer » des données à l’aide de l’instruction « return », les fonctions du générateur Python introduisent une nouvelle instruction ou mot-clé « yield » pour Python. Semblable aux instructions de retour, son rôle principal est de réguler l’exécution d’une fonction génératrice. Mais l’instruction Python « yield » présente quelques différences significatives dans l’exécution.

    Lorsque vous utilisez une expression génératrice ou une fonction génératrice, vous renvoyez un itérateur unique appelé « générateur ». Ce générateur peut être utilisé en l’affectant à une variable. Lorsque vous appelez des méthodes spécifiques sur le générateur, telles que next()le code inclus dans la fonction est exécuté jusqu’à l’instruction « yield ».

    L’instruction « yield » de Python amène le programme à interrompre l’exécution de la fonction appelante et à renvoyer la valeur qui a été renvoyée. (En revanche, « return » termine l’exécution de la fonction). L’état d’une fonction est enregistré lorsqu’elle est suspendue.

    Le pointeur d’instruction, la pile interne et toute gestion d’exception sont tous inclus, ainsi que toutes les liaisons de variables propres au générateur.

    Chaque fois que vous appelez l’une des méthodes du générateur, vous pouvez continuer l’exécution de la fonction en conséquence. Cela permet à l’ensemble de l’évaluation de la fonction de reprendre immédiatement après le « rendement ».

    Une autre distinction est que les fonctions génératrices construisent et renvoient un objet générateur ; ils n’exécutent même pas une fonction. Le code dans les fonctions du générateur ne s’exécute que lorsque l’objet générateur next() méthode est invoquée.

    Implémentation des fonctions du générateur

    Voyons comment les fonctions du générateur peuvent être implémentées en Python. Nous allons implémenter l’itérateur de génération de nombres pairs, comme indiqué précédemment, mais avec l’aide de la fonction générateur cette fois :

    def list_even_generator():
    
       n=0
    
      
    
       n+=2
    
       yield n
    
      
    
       n+=2
    
       yield n
    
      
    
       n+=2
    
       yield n
    
      
    
    even_nos=list_even_generator()
    
    print(next(even_nos))
    
    print(next(even_nos))
    
    print(next(even_nos))

    Ce qui donne cette sortie :

    Ici, nous développons une fonction génératrice avec trois déclarations de rendement. Lorsque cette fonction est appelée, elle renvoie un générateur, un objet itérateur. Les next() La fonction est ensuite utilisée pour extraire des éléments de cet objet.

    Nous pouvons calculer la valeur du premier rendement à partir de la déclaration d’impression, qui est « 2 », la valeur de la deuxième déclaration de rendement à partir de la déclaration d’impression, qui est « 4 », et la valeur de la troisième déclaration de rendement à partir de la déclaration d’impression , qui est « 6 ».

    Comme on peut le constater, la fonction génératrice est considérablement plus simple que notre itérateur, qui est basé sur des classes.

    Note: Le code ci-dessus n’implique pas de valeur « max », ce qui signifie que cet objet itérable itère sur une séquence infinie de nombres pairs.

    Maintenant, changeons le code ci-dessus, en utilisant le « Ne répétez pas votre principe » et en enveloppant les instructions dans une boucle while, en prenant une valeur max cette fois :

    def list_even_generator(max):
    
       n=0
    
      
    
       while n<=max:
    
           yield n
    
           n+=2
    
      
    
    even_nos=list_even_generator(5)
    
    print(next(even_nos))
    
    print(next(even_nos))
    
    print(next(even_nos))
    

    Ce qui donne cette sortie :

    Et puis, le StopException est relevé.

    Les stopException une exception est levée lorsque la valeur « n » atteint « 4 » et dépasse la valeur maximale de « 5 ».

    Vous pouvez voir dans le code que nous n’avons jamais explicitement spécifié le __iter__ méthode, la __next__ méthode, ou a soulevé une StopIteration exception dans notre générateur.

    Au lieu de cela, les générateurs gèrent les choses automatiquement, ce qui rend la programmation beaucoup plus simple à comprendre.

    Pourquoi avons-nous besoin de générateurs ?

    Lors de leur création, les itérateurs ne calculent pas la valeur de chaque élément. Lorsque vous le demandez, ils ne font que le calculer. Évaluation paresseuse c’est ce que nous appelons cela.

    Lorsque vous avez besoin de calculer à partir d’une énorme collection de données, une évaluation paresseuse est utile. Pendant que l’ensemble de données est en cours de calcul, cela vous permet d’utiliser les données immédiatement.

    Par exemple, pour lire un csv_file en Python, généralement, une méthode appelée csv_reader est utilisé. Considérons le cas d’utilisation où nous devons calculer le nombre de lignes dans l’ensemble de données. Le code apparaîtra comme ci-dessous :

    dataset = csv_reader("dataset.csv")
    
    row_cnt = 0
    
    
    
    for row in dataset:
    
        row_cnt += 1
    
    
    
    print("Row count is ", row_cnt)

    Quelle serait la mise en œuvre de la csv_reader() méthode? Cela nécessiterait d’ouvrir l’ensemble de données et de charger son contenu dans le tableau attribué. Chaque ligne du fichier CSV peut être ajoutée en tant qu’élément au tableau, et en calculant la longueur du tableau, nous pouvons trouver le nombre de lignes :

    def csv_reader(file_name):
    
        file = open(file_name)
    
        res = file.read().split("\n")
    
        return res

    Cette implémentation fonctionne parfaitement si le jeu de données est petit. Dans le cas de fichiers volumineux, nous allons rencontrer l’erreur d’exception de mémoire. La raison en est que la déclaration file.read().split() charge l’ensemble de l’ensemble de données dans la mémoire en une seule fois, ce qui entraîne une erreur de mémoire et l’ordinateur/le système peut même tomber en panne.

    La caractéristique principale d’une fonction génératrice est de sauvegarder l’état des variables impliquées dans la fonction. Par conséquent, l’utilisation d’une fonction de générateur pour lire un grand ensemble de données n’entraînera pas d’erreur de mémoire car elle ne chargera pas tout dans la mémoire en même temps. Le processus est exécuté de manière itérative sur chaque ligne.

    Le code est affiché ci-dessous :

    def csv_reader(file_name):
    
        for row in open(file_name, "r"):
    
            yield row

    Ici, le fichier est ouvert et itéré un par un, en ajoutant chaque ligne au tableau attribué donné (dans le code principal) en une itération. La sortie suivante de ce code doit être générée sans aucune erreur de mémoire :

    Le code accède d’abord au fichier, puis parcourt chaque ligne, produisant chaque ligne plutôt que de la renvoyer.

    Similaire est le cas d’utilisation de la génération d’une séquence infinie, ce qui n’est pas rare dans de nombreuses applications.

    En Python, la méthode range() est utilisé pour obtenir une suite finie. Comme le montre l’exemple ci-dessous :

    Ce qui donne cette sortie :

    Cependant, pour obtenir une suite infinie, range() ne peut pas être utilisé et des fonctions de générateur sont nécessaires pour que l’ordinateur ne manque pas de sa mémoire finie. Le code sera :

    def inf_seq():
    
        n = 0
    
        while True:
    
            yield n
    
            n += 1

    Tout d’abord, la variable « n » est initialisée avant de commencer une boucle sans fin. Après cela, vous donnez immédiatement « n » pour enregistrer l’état. Cela ressemble au fonctionnement de la plage.

    En utilisant le next() , l’objet générateur générera l’élément suivant. Si nous essayons d’itérer sur cette liste infinie en utilisant un pour la bouclenous finirons par imprimer une liste interminable de valeurs et l’ordinateur plantera ou continuera à produire des valeurs jusqu’à ce que vous fassiez une interruption au clavier.

    #…

    Share. Facebook Twitter Pinterest LinkedIn WhatsApp Reddit Email
    Add A Comment

    Leave A Reply Cancel Reply

    Catégories

    • Politique de cookies
    • Politique de confidentialité
    • CONTACT
    • Politique du DMCA
    • CONDITIONS D’UTILISATION
    • Avertissement
    © 2023 DéveloppeurWeb.Com.

    Type above and press Enter to search. Press Esc to cancel.