Благодаря некоторым замечательным людям на SO, я открыл возможности, предлагаемые collections.defaultdict
, в частности, в удобочитаемости и скорости. Я использовал их с успехом.
Теперь я хотел бы реализовать три уровня словарей: два верхних defaultdict
и самый нижний int
. Я не нахожу подходящий способ сделать это. Вот моя попытка:
from collections import defaultdict
d = defaultdict(defaultdict)
a = [("key1", {"a1":22, "a2":33}),
("key2", {"a1":32, "a2":55}),
("key3", {"a1":43, "a2":44})]
for i in a:
d[i[0]] = i[1]
Теперь это работает, но следующее, которое является желаемым поведением, не:
d["key4"]["a1"] + 1
Я подозреваю, что я должен был где-то объявить, что второй уровень defaultdict
имеет тип int
, но я не нашел, где и как это сделать.
Причина, по которой я использую defaultdict
в первую очередь, заключается в том, чтобы избежать инициализации словаря для каждого нового ключа.
Любое более элегантное предложение?
Спасибо питонерам!
источник
multiprocessing
это значит, что он не хочет отправлять их туда-сюда.d[new_key]
к нему обращаются, он вызывает лямбду, которая создаст новуюdefaultdict(int)
. И когдаd[existing_key][new_key2]
будет осуществлен доступ,int
будет создан новый .multiprocessing
и что такое именованная функция уровня модуля? Этот вопрос вытекает.Еще один способ сделать вложенный defaultdict с возможностью выбора - использовать частичный объект вместо лямбды:
Это будет работать, потому что класс defaultdict доступен глобально на уровне модуля:
источник
Посмотрите на ответ nosklo здесь для более общего решения.
Тестирование:
Вывод:
источник
В соответствии с запросом @ rschwieb
D['key'] += 1
, мы можем расширить предыдущее , переопределив добавление определением__add__
метода, чтобы сделать его более похожим наcollections.Counter()
Сначала
__missing__
будет вызвано создание нового пустого значения, которое будет передано__add__
. Мы проверяем значение, рассчитывая на пустые значенияFalse
.См. Эмуляция числовых типов для получения дополнительной информации о переопределении.
Примеры:
Вместо того, чтобы проверять аргумент - это Number (очень не python, amirite!), Мы можем просто предоставить значение по умолчанию 0 и затем выполнить операцию:
источник
Поздно к вечеринке, но для произвольной глубины я просто обнаружил, что делаю что-то вроде этого:
Хитрость заключается в том, чтобы сделать сам
DeepDict
экземпляр действительной фабрикой для создания пропущенных значений. Теперь мы можем делать такие вещи, какисточник
Нет ошибок снова. Неважно, сколько уровней вложено. не появляется также ошибка
дд = DefaultDict ({ "1": 333333})
источник