ホームページ >バックエンド開発 >Python チュートリアル >Elixir の for ループと内包表記 - 命令型コードの変換

Elixir の for ループと内包表記 - 命令型コードの変換

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-04 15:05:11117ブラウズ

For loops and comprehensions in Elixir - transforming imperative code

この記事では、Python での for ループと内包表記の一般的な使用方法、既存のループを分析する方法、およびそれらを Elixir で同等の式に変換する方法について説明します。 Enum モジュールと comprehension.

の関数を使用します。

次の点に焦点を当てます:

  • 関数 (map) を使用してデータのコレクションを変換する
  • コレクションに値をフィルタリングする、またはコレクションから値をフィルタリングする (filter)
  • 平均などの単一の集計値または構造を生成します (reduce または fold)

最後に、3 つすべてを組み合わせた基本的な例を示します。

パイソン

for ループ

Python では、for ループ は通常、インターリーブ処理を特徴とし、ステップは同じ句または本体に結合されます。最初の 2 つの偶数を二乗する例を次に示します。

result = 0
for num in [1, 2, 3, 4, 5]:
    if num % 2 == 0:
        result += num ** 2
print(result)  # Output: 20

このインターリーブされたボディの 1 つの課題は次のとおりです。

  1. 各ステップを確認して…
  2. それがどのタイプのステップであるかを考えてください。

各ステップを分解すると、行われている変換を理解し、不要なステップを削除して、それらのステップを別の言語構造または高レベルの関数に書き直すことができます。

上記の関数に注釈を付けると、次の結果が得られます。

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

手順

結果として、手順の順序は次のとおりです。

  1. フィルター 「アウト」奇数/「イン」偶数
  2. の数値 (例: 2) を対応する平方数 (例: 4) にマッピングします
  3. を偶数の二乗の合計に減算します

内包表記

Python の

内包表記 は、リストや辞書などのコレクションを マップ し、フィルター する簡単な方法です。結果を削減する方法は提供されていませんが、sum のような組み込み関数を使用して上記を変換し、内包表記の結果を処理することができます:

result = sum(num ** 2 for num in [1, 2, 3, 4, 5] if num % 2 == 0)
print(result)  # Output: 20

内包表記を使用すると、式は map ステップ (num ** 2) と filter ステップ (if num % 2) を分割します。 == 0) 明らかに。 sum は、ここでの reduce ステップです。

Python ではこれらの内包表記をざっと読むのは簡単で、内包表記の複雑さに有用な上限を設けます。

このような背景と、Python の処理構造の構造と制限をよりよく理解した上で、Elixir の内包表記と Enum パイプラインを使用して上記の Python コードを書き直してみましょう!

マッピング: Enum.map とジェネレーター

ステップを平方数にするにはどうすればよいでしょうか? Elixir では、それは簡単です!

Enum.map の使用:

result = 0
for num in [1, 2, 3, 4, 5]:
    if num % 2 == 0:
        result += num ** 2
print(result)  # Output: 20

および内包表記の使用 (for):

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

<- は ジェネレーター 式を表し、do:

の後の for 式の本体で使用される値を生成します。

フィルタリング: Enum.filter とフィルター

Enum.filter (または Enum.reject) を使用すると簡単に実行できます:

result = sum(num ** 2 for num in [1, 2, 3, 4, 5] if num % 2 == 0)
print(result)  # Output: 20

奇数を二乗する前にフィルターで除外したいので、それをパイプラインの適切な場所 (Enum.map の前) に配置します。

内包表記を使用すると、内包表記の先頭に 2 番目の式、つまりブール テストであるフィルターを追加できます。

Enum.map([1, 2, 3, 4, 5], & &1 ** 2)

rem(n, 2) == 0 式は、false (または nil) を返す要素をすべて破棄し、実際に本体に渡される数値として [2, 4] を残します (do: n ** 2)。

減らす -> Enum.reduce とreduce:

Enum.reduce/2 を使用すると、アキュムレータに加算することで二乗数値のリストをその合計に変換できます。アキュムレータの初期値 (Enum.reduce/3) を指定しない場合、最初の要素はアキュムレータの初期値として使用されます。これはここで便利です:

for n <- [1, 2, 3, 4, 5], do: n ** 2

内包表記を使用すると、Python の同等の機能よりもさらに強力になります。頭に別の句を追加することで、reduce ステップを追加できます。

[1, 2, 3, 4, 5]
|> Enum.filter(& rem(&1, 2) == 0)
|> Enum.map(& &1 ** 2)




</p>
<p>ここで 2 つの変更を加えます:</p>

<ol>
<li>reduce: 0 句を先頭に追加して、初期値が 0 の値を蓄積することを指定します</li>
<li>現在の 2 乗値を加算できる acc 値 (アキュムレータ) を取得するために for 本体を変更します。</li>
</ol>

<h2>
  
  
  組み込み関数: Enum.sum
</h2>

<p>原則として、変換したいデータは可能な限り最高レベルの方法で表現する必要があります。 Enum.reduce を最低レベルの関数変換と考えると便利です。これは、他のすべてのデータ処理を Enum.reduce に関して書き換えることができるためです。</p>

<p>Enum モジュールには、多くの高レベル関数が含まれており、通常、値のリストを合計、最大値、最小値などの単一の集計値に削減することが含まれます。この場合、要素の合計が必要です。</p>

<p>Enum パイプラインの場合、これは簡単です:<br>
</p>

<pre class="brush:php;toolbar:false">for n <- [1, 2, 3, 4, 5], rem(n, 2) == 0, do: n ** 2

これらの高レベルの集計関数を内包表記で表す方法はないため、Python で行ったのと同様に、次のように内包表記の出力を Enum.sum 呼び出しにパイプできます。

[1, 2, 3, 4, 5]
|> Enum.filter(& rem(&1, 2) == 0)
|> Enum.map(& &1 ** 2)
|> Enum.reduce(& &1 + &2)

異なる形式の混合は、特に変換が単純なものである場合、読者の精神的負担が軽減されるため、一般的に避けるべきです。上記のreduce:形式は、低レベルであるにもかかわらず、実際には読みやすいです。

どの Elixir 式が優れていますか?

要約すると、慣用的と考えられる 2 つの形式ができました。 Enum パイプラインの場合:

result = 0
for num in [1, 2, 3, 4, 5]:
    if num % 2 == 0:
        result += num ** 2
print(result)  # Output: 20

および内包表記:

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

読みやすいコードは、曖昧さや式でつまずくことなく、ざっと目を通せるものである必要があります。どちらの形式も次のようにその基準を満たしていると思います:

  1. それらは、Enum パイプラインまたは内包表記のいずれかの単一の一貫した形式に従います
  2. 各式は単一の処理ステップに対応します
  3. 中断することなく上から下または左から右に読むことができます

結論

これらの変換の記述は、Elixir ではいくつかの異なる方法で行うことができます。特にコードが変更され、時間の経過とともに処理が複雑になると、コードベースのスタイルが変化しやすくなります。

PureType は、Enum パイプラインと内包表記を分解および分析して、それらを最も明確かつ慣用的な形式で表現し、ユーザーの好みを学習して、チームの他のメンバーにとってコードの読みやすさと明瞭さを向上させることができます。今すぐ試してみてください!

以上がElixir の for ループと内包表記 - 命令型コードの変換の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。