schedule2019-04-23

複数の配列をまとめてfor文処理するzip()の使い方 | Python

2つの配列をfor文を使って同時に処理したいときに zip() を使います。 zip() の基本的な使い方に加え、配列の長さが異なるときの挙動や類似する関数も紹介します。

動作確認:Python 3.7

zip()

for文の前に、まずはzip()の使い方から見ていきます。 小文字と大文字の配列をzip()に入れてみます。

lower = ['a', 'b', 'c']
upper = ['A', 'B', 'C']

print(zip(lower, upper))
# <zip object at 0x00CE4468>

そのままだとzipオブジェクトになって良く分からないので、list型に変換します。

print(list(zip(lower, upper)))
# [('a', 'A'), ('b', 'B'), ('c', 'C')]

2つの配列が順番にペアを作って配列になりました。

for文でのzip()

続いてzip()がよく使われる、for文です。

lower = ['a', 'b', 'c']
upper = ['A', 'B', 'C']

for pair in zip(lower, upper):
  print(pair)

"""出力
('a', 'A')
('b', 'B')
('c', 'C')
"""

list型に変換せず、zipオブジェクトのまま扱えます。

for l, u in zip(lower, upper):
  print(l, u)

"""出力
a A
b B
c C
"""

要素をタプルで受け取るため個別の変数にも渡せます。 こちらの方が扱いやすいですね。

2つ以上の配列をまとめられる

3つの配列やもっと多い配列もまとめられます。

lower = ['a', 'b', 'c']
upper = ['A', 'B', 'C']
number = [0, 1, 2]

print(list(zip(lower, upper, number)))
# [('a', 'A', 0), ('b', 'B', 1), ('c', 'C', 2)]

配列の長さが異なる場合は短い方

配列の長さが異なる場合は、短い方に合わせられます。

lower = ['a', 'b', 'c']
upper = ['A', 'B', 'C', 'D', 'E']

print(list(zip(lower, upper)))
# [('a', 'A'), ('b', 'B'), ('c', 'C')]

upperの'D'が切れています。

長い方を基準に扱うときは itertoolsを使う

配列の長さが不明だったりして、長い方の配列に合わせたいときもある。 そんな時は、itertoolszip_longest()を使います。

importが必要です。

from itertools import zip_longest

lower = ['a', 'b', 'c']
upper = ['A', 'B', 'C', 'D', 'E']

print(list(zip_longest(lower, upper)))
# [('a', 'A'), ('b', 'B'), ('c', 'C'), (None, 'D'), (None, 'E')]

足りない部分はNoneで補います。

文字列も扱える

文字列もzip()で扱うことができます。

str1 = 'パトカー'
str2 = 'タクシー'

print(list(zip(str1, str2)))
# [('パ', 'タ'), ('ト', 'ク'), ('カ', 'シ'), ('ー', 'ー')]

result = ''
for s1, s2 in zip(str1, str2):
    result += s1 + s2

print(result)
# パタトクカシーー

これは言語処理100本ノック 2015の文字列を結合する問題からの抜粋です。

  1. 「パトカー」+「タクシー」=「パタトクカシーー」
    「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

以前解いたときの解法を見返したら、別解が10個ぐらいあって自分に引いた。。。

参考

あわせてどうぞ