Dans cet article, nous aborderons quelques utilisations courantes des boucles for et des compréhensions en Python, comment analyser une boucle existante et comment les transformer en leurs expressions équivalentes dans Elixir, en utilisant les fonctions du module Enum et des compréhensions.
Nous nous concentrerons sur :
Nous terminerons par un exemple basique qui combine les trois !
En Python, les for boucles comportent généralement un traitement entrelacé - les étapes sont combinées dans la même clause ou le même corps. Voici un exemple qui met au carré les deux premiers nombres pairs :
result = 0 for num in [1, 2, 3, 4, 5]: if num % 2 == 0: result += num ** 2 print(result) # Output: 20
Un défi de ce corps entrelacé est de :
Séparer chaque étape vous permet de comprendre les transformations en cours, d'éliminer celles qui sont inutiles et de réécrire ces étapes dans une autre construction de langage ou une fonction de niveau supérieur.
Annoter la fonction ci-dessus entraîne :
result = 0 for num in [1, 2, 3, 4, 5]: ## Filter if num % 2 == 0: ## Reduce (result += ) and Map (num ** 2) result += num ** 2 print(result) # Output: 20
En conséquence, l'ordre des étapes est :
Compréhensions en Python sont des moyens simples de mapper et de filtrer des collections telles que des listes et des dictionnaires. Ils n'offrent pas de moyen de réduire le résultat, mais nous pouvons utiliser des fonctions intégrées comme sum pour transformer ce qui précède afin de traiter le résultat de la compréhension :
result = sum(num ** 2 for num in [1, 2, 3, 4, 5] if num % 2 == 0) print(result) # Output: 20
Avec les compréhensions, l'expression divise l'étape map (num ** 2) et filter (si num % 2 == 0) clairement. la somme est l'étape réduire ici.
Il est facile de parcourir ces expressions de compréhension en Python, et cela place une limite supérieure utile à la complexité d'une compréhension.
Avec ce contexte et une meilleure compréhension de la structure et des limites des constructions de traitement de Python, passons à la réécriture du code Python ci-dessus en utilisant les compréhensions d'Elixir et les pipelines Enum !
Comment pouvons-nous écrire l'étape en carrés ? Dans Elixir, c'est simple !
Utilisation d'Enum.map :
result = 0 for num in [1, 2, 3, 4, 5]: if num % 2 == 0: result += num ** 2 print(result) # Output: 20
et en utilisant des compréhensions (pour) :
result = 0 for num in [1, 2, 3, 4, 5]: ## Filter if num % 2 == 0: ## Reduce (result += ) and Map (num ** 2) result += num ** 2 print(result) # Output: 20
Le <- représente une expression générateur, générant des valeurs à utiliser dans le corps de l'expression for, après do:
Facile à faire avec Enum.filter (ou Enum.reject) :
result = sum(num ** 2 for num in [1, 2, 3, 4, 5] if num % 2 == 0) print(result) # Output: 20
Nous voudrons filtrer les nombres impairs avant qu'ils ne soient mis au carré, nous les plaçons donc au bon endroit dans le pipeline - avant Enum.map.
A l'aide des compréhensions, on peut ajouter une deuxième expression en tête de la compréhension, un filtre, qui est un test booléen :
Enum.map([1, 2, 3, 4, 5], & &1 ** 2)
L'expression rem(n, 2) == 0 élimine ensuite tous les éléments qui renvoient faux (ou nul), laissant [2, 4] comme nombres réellement transmis au corps (do : n ** 2) de la compréhension.
En utilisant Enum.reduce/2, nous pouvons convertir une liste de nombres au carré en leur somme en l'ajoutant à un accumulateur. Le premier élément est utilisé comme valeur initiale de l'accumulateur si on ne précise pas de valeur initiale pour l'accumulateur (Enum.reduce/3), et c'est pratique ici :
for n <- [1, 2, 3, 4, 5], do: n ** 2
Avec les compréhensions, nous avons encore plus de puissance que l'équivalent Python. Nous pouvons ajouter une étape de réduction en ajoutant une autre clause en tête :
[1, 2, 3, 4, 5] |> Enum.filter(& rem(&1, 2) == 0) |> Enum.map(& &1 ** 2) </p> <p>faire deux changements ici :</p> <ol> <li>ajout d'une clause réduire: 0 en tête, pour préciser que l'on va accumuler une valeur dont la valeur initiale est 0</li> <li>changer le corps for pour capturer une valeur acc (l'accumulateur) à laquelle nous pouvons ajouter la valeur au carré actuelle.</li> </ol> <h2> Fonctions intégrées : Enum.sum </h2> <p>En règle générale, nous devons exprimer les données que nous souhaitons transformer de la manière la plus élevée possible. Il est utile de considérer Enum.reduce comme la transformation fonctionnelle de niveau le plus bas, puisque tous les autres traitements de données peuvent être réécrits en fonction de celle-ci.</p> <p>Le module Enum contient de nombreuses fonctions de niveau supérieur, impliquant généralement la réduction d'une liste de valeurs à une seule valeur globale, comme une somme, un maximum ou un minimum. Dans ce cas, nous aimerions la somme des éléments.</p> <p>Pour les pipelines Enum, c'est simple :<br> </p> <pre class="brush:php;toolbar:false">for n <- [1, 2, 3, 4, 5], rem(n, 2) == 0, do: n ** 2
Il n'existe aucun moyen de représenter ces fonctions d'agrégation de haut niveau dans les compréhensions, nous pouvons donc diriger le résultat de la compréhension vers un appel Enum.sum comme ceci, de la même manière que nous l'avons fait en Python :
[1, 2, 3, 4, 5] |> Enum.filter(& rem(&1, 2) == 0) |> Enum.map(& &1 ** 2) |> Enum.reduce(& &1 + &2)
Le mélange de différentes formes doit généralement être évité, surtout si la transformation est simple, car cela entraîne moins de charge mentale pour le lecteur - la forme réduire : ci-dessus est en fait plus claire à lire bien qu'elle soit de niveau inférieur.
Pour résumer, nous nous retrouvons avec deux formes qui pourraient être considérées comme idiomatiques. Pour les pipelines Enum :
result = 0 for num in [1, 2, 3, 4, 5]: if num % 2 == 0: result += num ** 2 print(result) # Output: 20
et compréhensions :
result = 0 for num in [1, 2, 3, 4, 5]: ## Filter if num % 2 == 0: ## Reduce (result += ) and Map (num ** 2) result += num ** 2 print(result) # Output: 20
Le code facile à lire doit être simple à parcourir, sans ambiguïté ni trébuchement sur les expressions. Je pense que les deux formulaires remplissent ce critère, comme :
L'écriture de ces transformations peut être effectuée de plusieurs manières différentes dans Elixir, et il est facile pour une base de code de varier les styles, d'autant plus que le code change et que le traitement devient plus compliqué avec le temps.
PureType peut décomposer et analyser les pipelines et les compréhensions Enum pour les représenter sous leur forme la plus claire et la plus idiomatique, en apprenant vos préférences et en augmentant la lisibilité et la clarté de votre code pour les autres membres de l'équipe. Essayez-le aujourd'hui !
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!