【Python】組み込み関数zip()でディクショナリを初期化する

zip()はディクショナリの初期化に向いている。

zip()の基本的な使い方

公式ドキュメント2. 組み込み関数 — Python 3.4.3 ドキュメントより

zip(*iterables)
それぞれのイテラブルから要素を集めたイテレータを作ります。

この関数はタプルのイテレータを返し、その i 番目のタプルは引数シーケンスまたはイテラブルそれぞれの i 番目の要素を含みます。このイテレータは、入力のイテラブルの中で最短のものが尽きたときに止まります。単一のイテラブル引数が与えられたときは、1-タプルのイテレータを返します。引数がなければ、空のイテレータを返します。

つまり、zip()は複数のリストなどを引数にできる。1つのリストだけを渡すと、ただのイテレータが作られる。イテレータはタプルであることを忘れずに。

# 10以下の奇数の和を計算
# zipの引数に1つのタプルを渡している
a = (1,3,5,7,9)
s = 0
for it in zip(a):
    s += it[0]
print(s)  # > 25

上のはzip()の引数に1つだけを渡してた自明なコード。zip()がイテレータを作っていることが確認できる。
2つ以上の引数を渡すと、なんとなく便利そうな感じがある。

# zip()に2つのリストを渡す
x = [c for c in 'abcde']  # ['a', 'b', 'c', 'd', 'e']
y = [n for n in range(5)] # [0, 1, 2, 3, 4]
for it in zip(x, y):
    print(it)

実行結果は、次のとおり。

('a', 0)
('b', 1)
('c', 2)
('d', 3)
('e', 4)

zip()でディクショナリを初期化

たとえば文章中に現れるアルファベットを数えたいとして、アルファベットを数えるためのディクショナリを作ります。

# アルファベットをキーとしたディクショナリ(アルファベットの順番は適当)
cnt_abc = {'y': 0, 'd': 0, 'm': 0, 't': 0, 'w': 0, 'r': 0, 'l': 0, 'k': 0, 'g': 1, 'i': 0, 'v': 0, 'q': 0, 'h': 0, 'a': 0, 'p': 0, 'o': 0, 'u': 0, 'j': 0, 'c': 0, 'f': 0, 'z': 0, 's': 0, 'e': 0, 'b': 0, 'x': 0, 'n': 0}

で、これを手作業で打つのはめんどくさい。ここで、zip()が役に立つ。

# t = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
t = tuple(string.ascii_lowercase)
m = [0] * 26
cnt_abc = {}
for it in zip(t, m):
    cnt_abc[ it[0] ] = it[1]

もっと短く書くなら、こう。

cnt_abc = dict(zip(tuple(string.ascii_lowercase), [0] * 26))