Подтвердить что ты не робот

Добавление в список в словаре 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 

но почему?

4b9b3361

Ответ 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)