Есть ли способ сделать defaultdict также значением по умолчанию для defaultdict? (т.е. рекурсивный стандарт бесконечного уровня по умолчанию?)
Я хочу уметь:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Итак, я могу x = defaultdict(defaultdict)
, но это только второй уровень:
x[0]
{}
x[0][0]
KeyError: 0
Есть рецепты, по которым это можно сделать. Но можно ли это сделать, просто используя обычные аргументы defaultdict?
Обратите внимание, что здесь спрашивается, как сделать рекурсивный defaultdict бесконечного уровня, чтобы он отличался от Python: defaultdict of defaultdict? , который заключался в том, как сделать двухуровневое определение по умолчанию.
Я, вероятно, просто воспользуюсь шаблоном связки , но когда я понял, что не знаю, как это сделать, это меня заинтересовало.
python
recursion
defaultdict
Корли Бригман
источник
источник
Ответы:
Для произвольного количества уровней:
Конечно, вы также можете сделать это с помощью лямбды, но я считаю, что лямбды менее читабельны. В любом случае это выглядело бы так:
источник
lambda
это не сработает.В других ответах здесь рассказывается, как создать объект,
defaultdict
содержащий «бесконечно много»defaultdict
, но они не могут удовлетворить то, что, как я думаю, могло быть вашей первоначальной потребностью, а именно иметь двухуровневый стандарт по умолчанию.Возможно, вы искали:
Причины, по которым вы можете предпочесть эту конструкцию, следующие:
defaultdict
быть чем-то другим, кроме словаря, например:defaultdict(lambda: defaultdict(list))
илиdefaultdict(lambda: defaultdict(set))
источник
lambda
форма правильная - потому чтоdefaultdict(something)
возвращает объект, подобный словарю, ноdefaultdict
ожидает вызываемого! Спасибо!dict(result)
Для этого есть отличный трюк:
Затем вы можете создать свой
x
с помощьюx = tree()
.источник
Подобно решению BrenBarn, но не содержит
tree
дважды имени переменной , поэтому работает даже после изменений в словаре переменных:Затем вы можете создавать каждую новую
x
с помощьюx = tree()
.Для этой
def
версии мы можем использовать область закрытия функции, чтобы защитить структуру данных от недостатка, когда существующие экземпляры перестают работать, еслиtree
имя повторяется. Выглядит это так:источник
Я бы также предложил больше реализации в стиле ООП, которая поддерживает бесконечное вложение, а также правильно отформатирована
repr
.Использование:
источник
*args
и,**kwargs
что позволяет ему работать какdefaultdict
, а именно создавать dict с ключевыми аргументами. Это полезно для переходаNestedDefaultDict
вjson.load
вот рекурсивная функция для преобразования рекурсивного dict по умолчанию в нормальный dict
источник
Я основал это на ответе Эндрю здесь. Если вы хотите загрузить данные из json или существующего dict в nester defaultdict, посмотрите этот пример:
https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775
источник