Kyam気まぐれブログ

ITや日常であった面白いこと

defaultdict()についてわかりやすくまとめて見た

ども Kyamです。

defaultdict()メソッドについて記録して行きたいと思います。

python3のリファレンスを読んでわかる人もいると思うので、下にurlを貼っておくので見てください。

http://docs.python.jp/3.3/library/collections.html#collections.defaultdict

主は読んでもなんとなくというか正直全然わかりませんでした。

といいますと、"新しいディクショナリ状のオブジェクト"がまず理解できなかったからです。

ですので、私はdefaultdictの使用例を見ながら友人のサポート付きで理解していきました。

それでは、リファレンスからプログラムを引用して理解していきましょう。

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> list(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

簡単に言えばこのソースコード

それぞれの色に付属してある数をリスト型としてまとめているということです。

これは、最後の部分でわかると思います。でもこれではdefaultdict()が何をしているのかわからないので1行ずつ読んで行きましょう

まず、

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

この文章は、見ての通り、

sはリスト型で中に5つのタプルの要素を持っている状態です。

ここでは、特にkey値とかvalue値などには別れていません。

リストの中にタプルがあり、それぞれのタプルに('',)

>>> d = defaultdict(list)

でこれは何をしているかというと以下のことをしています。

d={:[]}

「は??」となっているとおもいますが、言葉であらわすと理解できると思います。

デフォルトのvalue値にリストオブジェクト(型)が入ったdict型の変数dになる

ということです。

なかなかこれでは具体的にわからないと人もいると思うのでプログラミングで試して見ましょう。

>>> d=collections.defaultdict(list)
>>> d
defaultdict(<class 'list'>, {})

 

と返してきますこれでもよくわからないので具体的に値を入れてきましょう。

では

次にkey名をblueとしデフォルトのvalueオブジェクトがリストオブジェクトなのでappend()で12を入れていきましょう

 

>>> d['blue'].append(12)
>>> d
defaultdict(<class 'list'>, {'blue': [12]})

 

一個だとわかりづらいので何個か入れていきましょう

 

>>> d['blue'].append(23)
>>> d['blue'].append(2)
>>> d['yellow'].append(4)
>>> d['red'].append(1)
>>> d['yellow'].append(31)
>>> d['red'].append(52)
>>> d
defaultdict(<class 'list'>, {'blue': [12, 23, 2], 'yellow': [4, 31], 'red': [1, 52]})

 

お分りいただけたでしょうか。

このようにデフォルトのオブジェクトがリストであるから、このようなことが可能なのです。

それではデフォルトのオブジェクトが違うオブジェクトならどうなるのでしょうか?

それではデフォルトをint型にしてみて同じ動作をしていきましょう

>>> i=collections.defaultdict(int)
>>> i
defaultdict(<class 'int'>, {})
>>> i['blue'].append(12)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'append'

 

エラーが発生しました!

それはそうですよねintオブジェクトにはappend()なんてないんですからつかえません。このように指定したオブジェクトのメソッドを使うことは可能になります。

 

しかし、

注意 代入演算子は別物

>>> d['blue']=12
>>> d
defaultdict(<class 'list'>, {'blue': 12, 'yellow': [4, 31], 'red': [1, 52]})
>>> d['yellow']=12
>>> d['red']=12
>>> d
defaultdict(<class 'list'>, {'blue': 12, 'yellow': 12, 'red': 12})

このように代入演算子でvalueのオブジェクトも簡単に書き換えることができてしまうのです。この場合入っているのはint型なのです。ですから例で表すと、key値を'blue'で指定した場合、リスト型のメソッドはできないので注意してください!

 

しかしvalue値のデフォルトのオブジェクトは変わることはないので新しくkey値を入れた時はリスト型として入れることができるのです

 

それでは、先ほどのプログラムの続きの説明に戻っていきましょう

>>> for k, v in s:
...     d[k].append(v)

 for 文でsの要素はタプルであるためにこのようにkにはvにはを回ることに代入していって、defaultdict型のdにkey値とvalue値をそれぞれkとvを代入していきます

>>> list(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

よってdの要素はこのような形になるのです。

 ソースコードのまとめを以下のようにまとめておきます。

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
#リスト型 5つのタプル型 >>> d = defaultdict(list) # d={:[]} ー> value値のデフォルトオブジェクト(型)がlist
>>> for k, v in s: ... d[k].append(v)
#kという名のkey名にvという値をpush
... >>> list(d.items()) [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
#dの中身の表示

まとめ

お分りいただけたでしょうか??

defaultdict()は

変数としてはdict型ではあるが、デフォルトのvalue値のオブジェクトが指定されたオブジェクトになる

というメソッドなのです。

また他のメソッドも書いていきたいと思います

リクエストやわからないことがあるまたは、何か表現が間違っている場合などがあればどんどん書いてください!!!

やってはいけないことなどが書いてある場合がいってください。早急に消したいと思います。

 

 読むために必要なurl

8.3. collections — コンテナデータ型 — Python 3.3.6 ドキュメント

5. データ構造 — Python 3.6.1 ドキュメント

 より深く理解できたurl

Python defaultdictで辞書のキーの有無を気にせずに処理する - Librabuch