ZIPを使用してイテレータを並列処理する方法
はじめに
リスト内包表記を使用すると、式を適用することで、ソースリストを取得し、派生リストを簡単に取得できます。たとえば、リスト内の各要素に5を掛けたいとします。ここでは、単純なforループを使用してこれを行います。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] multiply_by_5 = [] for x in a: multiply_by_5.append(x*5) print(f"Output \n *** {multiply_by_5}")
出力
*** [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
リスト内包表記を使用すると、ループする式と入力シーケンスを指定することで同じ結果を得ることができます。
# List comprehension multiply_by_5 = [x*2 for x in a] print(f"Output \n *** {multiply_by_5}")
出力
*** [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
ここで、追加するリストがいくつかあるとしましょう。
# 1 . Create a List of Numbers list1 = [100, 200, 300, 400] list2 = [500, 600, 700, 800] # 2. Add the two lists to create a new list list3 = [] # Using a Loop. for i in range(len(list1)): added_value = list1[i] + list2[i] list3.append(added_value) print(f"Output \n*** {list3}")
出力
*** [600, 800, 1000, 1200]
ここで重要なのは、付加値の派生リスト(この場合はlist3)のアイテムが、インデックスによってソースリストのアイテムに直接関連していることです。
さて、zip処理に関しては、同じリスト整数のzipソリューションを次に示します。この場合、1つは100、200、300、400を含み、もう1つは500、600、700、800を含む整数の2つのリストです。もちろん、それらを定義して変数に割り当てることもできます。そして、それらはリストである必要はありません。
タプルなどの他のシーケンスである可能性があります。
つまり、これらの要素のペアを一緒に圧縮するので、list1の100とlist2の500が一緒に圧縮されます。タプルごとに、それらを反復処理しながら、タプルを変数aとbに解凍します。
list4 = [] list4 = [(a + b) for a, b in zip(list1, list2)] print(f"Output \n*** {list4}")
出力
*** [600, 800, 1000, 1200]
上記のソリューションは本当にクールに見えますが、コードに適用する前に知っておく必要のある深刻な問題があります。
入力イテレータの長さが異なる場合、zip組み込み関数は奇妙な動作をします。試してみましょう。
# add a new number to the list list1.append(1000) print(f"Output \n*** Length of List1 is {len(list1)} , Length of List2 is {len(list2)}") # run the zip against the list for addition. list5 = [(a + b) for a, b in zip(list1, list2)] print(f"*** {list5}")
出力
*** Length of List1 is 9 , Length of List2 is 4 *** [600, 800, 1000, 1200]
ここで、list3から追加された各番号を印刷すると、list1に追加された番号が欠落していることがわかります。これを追加し、list1に含めても、zipの出力には表示されません。
そして、これがzipの仕組みです。いずれかのイテレータが使い果たされるまで、タプルを維持します。したがって、list1はlist2に比べて多くのことを行う必要がありますが、最初に使い果たされてから、ループが終了します。
驚いたことに、例外なく通知されません。したがって、本番環境ではzipに十分注意する必要があります。
ziplongestと呼ばれるitertoolsのpython関数でこの問題のオプションがあります。
このzipが最も長いのは、イテレータの1つが使い果たされた場合でも継続します。
from itertools import zip_longest list6 = [] for a, b in zip_longest(list1, list2): if b is None: print(f" << do your logic here >> ") elif a is None: print(f" << do your logic here >> ") else: list6.append(a + b) print(f"Output \n*** {list6}")
<< do your logic here >> << do your logic here >> << do your logic here >> << do your logic here >> << do your logic here >>
出力
*** [600, 800, 1000, 1200]
結論:
-
複数のイテレータを並行して反復処理する場合は、zip機能が非常に便利です。
-
異なる長さのイテレータを渡すと、zip機能の動作が異なります。
-
異なる長さのイテレータを使用する場合は、zip_longestを使用してください。
-
JavaScriptを使用してHTMLリストを並べ替える方法は?
JavaScriptを使用してHTMLリストを並べ替えるには、コードは次のとおりです- 例 <!DOCTYPE html> <html> <body> <h1>Sorting list example</h1> <button>Click to sort</button> <ul class="animalList"> <li>Giraffe</li> <li>Camel</li> <li>Dog</li>
-
Java 9でProcessBuilderを使用してプロセスを作成するにはどうすればよいですか?
Java 9 ProcessHandleを追加しました プロセスAPIへのインターフェース プロセスクラスを強化します。 ProcessHandleインターフェースのインスタンスは、プロセスのステータスを照会できるようにするローカルプロセスを識別します プロセスの管理と管理、および ProcessHandle.Info PID を取得する必要があるため、ローカルコードを使用できます ローカルプロセスの。 ProcessBuilder クラスを使用して、個別のオペレーティングシステムプロセスを作成できます。以下の例では、「メモ帳」のプロセスを作成できます。 ProcessBuil