web-dev-qa-db-ja.com

Python辞書のリストに追加

このコードを書くよりエレガントな方法はありますか?

私がしていること:キーと日付があります。キーには多数の日付を割り当てることができるため、これを表すために日付のリストの辞書を作成しています。次のコードは正常に機能しますが、よりエレガントでPythonicな方法を望んでいました。

dates_dict = dict() 
for key,  date in cur:
    if key in dates_dict:
        dates_dict[key].append(date)
    else:
        dates_dict[key] = [date] 

以下が機能することを期待していましたが、NoneTypeには属性追加エラーがありません。

dates_dict = dict() 
for key,  date in cur:
    dates_dict[key] = dates_dict.get(key, []).append(date) 

これはおそらく、

print([].append(1)) 
None 

しかし、なぜ?

55
Michael Murphy

list.appendはインプレース操作であり、それをdates_dict[key]に割り当てているため、Noneを返します。したがって、次回dates_dict.get(key, []).appendを実行するとき、実際にはNone.appendを実行しています。それが失敗している理由です。代わりに、あなたは単に行うことができます

dates_dict.setdefault(key, []).append(date)

しかし、この目的のためだけに collections.defaultdict があります。このようなことができます

from collections import defaultdict
dates_dict = defaultdict(list)
for key, date in cur:
    dates_dict[key].append(date)

keyが辞書にない場合、これは新しいリストオブジェクトを作成します。

注:defaultdictは辞書にキーが見つからない場合、新しいリストを作成するため、意図しない副作用があります。たとえば、単に存在しないキーの値を取得する場合、新しいリストを作成して返します。

94
thefourtheye

このコードを書くよりエレガントな方法はありますか?

collections.defaultdict を使用します。

from collections import defaultdict

dates_dict = defaultdict(list)
for key, date in cur:
    dates_dict[key].append(date)
19
jfs

dates_dict[key] = dates_dict.get(key, []).append(date)dates_dict[key]Noneを返すため、list.appendNoneに設定します。

In [5]: l = [1,2,3]

In [6]: var = l.append(3)

In [7]: print var
None

collections.defaultdict を使用する必要があります

import collections
dates_dict = collections.defaultdict(list)
4