Добавление в список в словаре 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 без атрибута append error.
dates_dict = dict()
for key, date in cur:
dates_dict[key] = dates_dict.get(key, []).append(date)
Вероятно, это связано с тем, что
print([].append(1))
None
но почему?
Ответы
Ответ 1
list.append
возвращает None
, так как это операция на месте, и вы возвращаете ее обратно в dates_dict[key]
. Итак, в следующий раз, когда вы делаете 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
создаст новый список, если ключ не найден в словаре, у него будут непреднамеренные побочные эффекты. Например, если вы просто хотите получить значение для ключа, которого там нет, он создаст новый список и вернет его.
Ответ 2
Есть ли более элегантный способ написать этот код?
Используйте collections.defaultdict:
from collections import defaultdict
dates_dict = defaultdict(list)
for key, date in cur:
dates_dict[key].append(date)
Ответ 3
dates_dict[key] = dates_dict.get(key, []).append(date)
устанавливает dates_dict[key]
в None
как list.append
возвращает None
.
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)