zip操作

Definition:Zipping

zip操作とは、複数の系列(sequence)の同じ位置にある要素を相互に対応付け、それらを組(tupleなど)としてまとめる操作のことをいう。

2つの系列

A = [a₁, a₂, ..., aₙ]
B = [b₁, b₂, ..., bₘ]

に対して、zip操作は

[(a₁,b₁), (a₂,b₂), ..., (aₖ,bₖ)]

という系列を生成する。ここで k = min(n,m) であり、通常のzipでは最も短い系列の長さに達した時点で操作を終了する。

例えば、

zip([1, 2, 3], ["a", "b", "c"])

は、

[(1, "a"), (2, "b"), (3, "c")]

に相当する。

さらに一般化すると、zip操作は複数の系列を、それぞれの要素の位置(index)をキーとして横断的に対応付ける操作である。

各プログラミング言語におけるzip操作

言語操作・関数内容
Pythonzip()複数の系列を同じ位置で対応付ける
JavaScriptzip()は標準ではないmap()などを組み合わせて同様の処理ができる
Rubyzip()配列を同じ位置で対応付ける
Haskellzip2つのリストを対応付ける
Scalazipコレクションを対応付ける
Rustzip()Iterator同士を対応付ける
Kotlinzip()2つのコレクションを対応付ける
ClojuremapなどPythonのzip()に相当する処理を別の形で行う

実装例

names = ["Alice", "Bob", "Carol"]
scores = [85, 92, 78]

for name, score in zip(names, scores):
print(f"{name}: {score}点")

出力:

Alice: 85点
Bob: 92点
Carol: 78点

zip() は複数のリストを同じインデックスの要素同士でペアにして1つずつ取り出す。names[i] と scores[i] をインデックスで対応付ける代わりに、2つのリストを直接組にして走査できる。

リストの長さが異なる場合は、短い方に合わせて打ち切られる。

a = [1, 2, 3]
b = ["x", "y"]
print(list(zip(a, b))) # [(1, 'x'), (2, 'y')] ← 3は無視される

同じインデックス同士を掛け合わせる場合:

a = [1, 2, 3, 4]
b = [10, 20, 30, 40]

# 同じインデックス同士を掛け合わせる
products = [x * y for x, y in zip(a, b)]
print(products) # [10, 40, 90, 160]

ひとつずらして掛け合わせる場合は、リストを1つ分ずらしたものと元のリストを zip() で組ませればよい。

values = [1, 2, 3, 4, 5]

# 隣り合う要素同士を掛け合わせる(1つずらして掛け合わせる)
shifted_products = [x * y for x, y in zip(values, values[1:])]
print(shifted_products) # [2, 6, 12, 20]

values[1:] は先頭を1つ落としたリスト [2, 3, 4, 5] になるので、zip(values, values[1:]) は (1,2), (2,3), (3,4), (4,5) という隣接ペアを作る。ずらし幅を増やせば、2つ・3つ離れた要素同士の掛け合わせも同様に書ける。

# 2つ離れた要素同士を掛け合わせる
gap2_products = [x * y for x, y in zip(values, values[2:])]
print(gap2_products) # [3, 8, 15]

Mathematics is the language with which God has written the universe.





















数理統計学 機械学習