Python
 Computer >> コンピューター >  >> プログラミング >> Python

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を使用してください。


  1. 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>

  2. Java 9でProcessBuilderを使用してプロセスを作成するにはどうすればよいですか?

    Java 9 ProcessHandleを追加しました プロセスAPIへのインターフェース プロセスクラスを強化します。 ProcessHandleインターフェースのインスタンスは、プロセスのステータスを照会できるようにするローカルプロセスを識別します プロセスの管理と管理、および ProcessHandle.Info PID を取得する必要があるため、ローカルコードを使用できます ローカルプロセスの。 ProcessBuilder クラスを使用して、個別のオペレーティングシステムプロセスを作成できます。以下の例では、「メモ帳」のプロセスを作成できます。 ProcessBuil