Вопрос по dictionary, default-value, python – Python: list () как значение по умолчанию для словаря

20

У меня есть код Python, который выглядит следующим образом:

if key in dict:
  dict[key].append(some_value)
else:
  dict[key] = [some_value]

но я думаю, что должен быть какой-то способ обойти этоесли' заявление. Я старался

dict.setdefault(key, [])
dict[key].append(some_value)

а также

dict[key] = dict.get(key, []).append(some_value)

но оба жалуются наTypeError: unhashable type: 'список'", Любые рекомендации? Спасибо!

Похоже, у вас могут быть проблемы с ключами списка, не связанными со всем значением по умолчанию. Это, или вы случайно переключили некоторые аргументы в вашем реальном коде, который вы не сделалит, когда вы отправили его в SO. user2357112
Ваше исключение не имеет ничего общего с кодом, который вы разместили здесь. Это указывает на то, чтоkey вместо этого это объект списка, который не может быть хешируемым и поэтому не разрешен в качестве ключа словаря. Martijn Pieters
@tdelaney: из остальной части поста я полагаю, что ОП сделалdict = {} в какой-то момент. Плохая идеямаски встроенный. Исключение, еслиdict есть еще встроенная совсем другаяTypeError: descriptor 'setdefault' requires a 'dict' object but received a 'str' (дляstr значение вkey). Martijn Pieters
Ух ты. Большая ошибка с моей стороны. Я не понял, что я замаскировал встроенный в письменной формеdict = {}, Виноват. Спасибо! Fysx
В дополнение к Martijn 'ответ для установки значений по умолчанию, выМы столкнулись с проблемой использования имени класса Python в качестве имени переменной. Когда ты сказалdict.setdefault(key, [])вы на самом деле вызываете несвязанный метод setdefault для 'ДИКТ» Объект класса. Это лечитключ» как сам указатель и пытается использовать '[] в качестве индекса. Просто создайте свою собственную переменнуюmydict = dict() и вы получите дальше. tdelaney

Ваш Ответ

1   ответ
44

Лучший способ заключается в использованииcollections.defaultdict сlist дефолт:

from collections import defaultdict
dct = defaultdict(list)

Тогда просто используйте:

dct[key].append(some_value)

и словарь создаст новый список для вас, если ключ еще не в отображении.collections.defaultdict это подклассdict а в остальном ведет себя так же, как нормальныйdict объект.

При использовании стандарта,dictdict.setdefault() правильно устанавливаетdct[key] для вас по умолчанию, так что версия должна работать просто отлично. Вы можете связать этот звонок с:.append()

>>> dct = {}
>>> dct.setdefault('foo', []).append('bar')  # returns None!
>>> dct
{'foo': ['bar']}

Однако с помощьюdct[key] = dct.get(...).append() вызамещать значение дляdct[key] с выходом.append(), который .None

Это решение сократило мое время выполнения с 2 часов до 15 минут. У меня очень большие словари, и в тот момент, когда они достигают 30 миллионов записей, они замедляются из-за всех проверок, если ключ уже существует. Также стоит отметить, что я использовал график networkx, но накладные расходы памяти были нелепыми. Теперь со словарем по умолчанию тот же график, который загружал в ОЗУ 180 ГБ, теперь использует менее 20 ГБ при использовании словарей по умолчанию. Вы спасли жизнь user1697483

Похожие вопросы