Несколько уровней 'collection.defaultdict' в Python

Благодаря некоторым великим людям на Так, я обнаружил возможности, предлагаемые 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 во-первых должен избежать необходимости инициализировать словарь для каждого нового ключа.

Еще изящное предложение?

Спасибо pythoneers!

169
задан Morlock 8 April 2010 в 14:37
поделиться

2 ответа

Использование:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(int))

Это будет создавать новый defaultdict (int) всякий раз, когда осуществляется доступ к новому ключу в d .

325
ответ дан 23 November 2019 в 20:51
поделиться

Посмотрите ответ nosklo здесь для более общего решения.

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

Тестирование:

a = AutoVivification()

a[1][2][3] = 4
a[1][3][3] = 5
a[1][2]['test'] = 6

print a

Выход:

{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}
12
ответ дан 23 November 2019 в 20:51
поделиться
Другие вопросы по тегам:

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