キー毎にリストを作成したい場合に defaultdict 便利

時々ですが、キー毎に値をまとめたいと切ってあると思います。

イメージとしては以下の感じ。

# はじめの項目毎に何が有るかまとめたい
ham = [('foo', 'aaa'), ('bar', 'bbb'), ('foo', 'ccc')]

# キーが無いので最初に空のリストを作る必要が有る
# 2回回すことに成るのでなんか嫌
spam = {x[0]: [] for x in ham}
for key, value in ham:
    spam[key].append(value)

print(spam)
# => {'foo': ['aaa', 'ccc'], 'bar': ['bbb']}

上記コードでも良いんですが、 Python の標準ライブラリには defaultdict があるのでそれを利用すると便利。

上記は以下でかけます。

from collections import defaultdict

# はじめの項目毎に何が有るかまとめたい
ham = [('foo', 'aaa'), ('bar', 'bbb'), ('foo', 'ccc')]

# キーが無くても list で初期化された空のリストが返るので、以下のように利用できる。
spam = defaultdict(list)
for key, value in ham:
    spam[key].append(value)

print(spam)
# => defaultdict(<type 'list'>, {'foo': ['aaa', 'ccc'], 'bar': ['bbb']})

便利

他に利用する場合

引数を int にすると集計用に良いかもしれません。

例えば以下のイメージです。

from collections import defaultdict

# それぞれ何個ずつあるか知りたい
ham = ['foo', 'bar', 'foo', 'bar', 'hoge', 'hoge']

spam = defaultdict(int)
for key in ham:
    spam[key] += 1

print(spam)
# => defaultdict(<type 'int'>, {'foo': 2, 'bar': 2, 'hoge': 2})

でもこの場合は Counter 使うと対応できます。

from collections import Counter

# それぞれ何個ずつあるか知りたい
ham = ['foo', 'bar', 'foo', 'bar', 'hoge', 'hoge']

# ham で初期化
spam = Counter(ham)

print(spam)
# => Counter({'foo': 2, 'bar': 2, 'hoge': 2})

Python の標準ライブラリは色々有るので色々見てみると捗るかもしれません。