Python: конвертировать defaultdict в dict

Как я могу преобразовать defaultdict

number_to_letter
defaultdict(<class 'list'>, {'2': ['a'], '3': ['b'], '1': ['b', 'a']})

чтобы быть общим dict?

{'2': ['a'], '3': ['b'], '1': ['b', 'a']}

Ответ 1

Вы можете просто вызвать dict:

>>> a
defaultdict(<type 'list'>, {'1': ['b', 'a'], '3': ['b'], '2': ['a']})
>>> dict(a)
{'1': ['b', 'a'], '3': ['b'], '2': ['a']}

но помните, что defaultdict является dict:

>>> isinstance(a, dict)
True

просто с немного другим поведением, в том случае, когда вы пытаетесь получить доступ к отсутствующему ключу - который обычно поднимал бы KeyError - вместо default_factory:

>>> a.default_factory
<type 'list'>

Это то, что вы видите, когда вы print a перед тем, как появится словарный запас словаря.

Итак, еще один трюк, чтобы вернуть больше диктовидного поведения без фактического создания нового объекта, - это reset default_factory:

>>> a.default_factory = None
>>> a[4].append(10)
Traceback (most recent call last):
  File "<ipython-input-6-0721ca19bee1>", line 1, in <module>
    a[4].append(10)
KeyError: 4

но большую часть времени это не стоит проблем.

Ответ 2

Если ваш defaultdict рекурсивно определен, например:

from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] = "world"
data["good"]["day"] = True

еще один простой способ конвертировать defaultdict обратно в dict - использовать json module

import json
data = json.loads(json.dumps(data))

и, конечно же, значения, содержащиеся в вашем defaultdict, должны ограничиваться только поддерживаемыми json типами данных, но это не должно быть проблемой, если вы не намерены хранить классы или функции в dict.

Ответ 3

Если вам нужна рекурсивная версия для преобразования рекурсивного defaultdict в dict, вы можете попробовать следующее:

#! /usr/bin/env python3

from collections import defaultdict

def ddict():
    return defaultdict(ddict)

def ddict2dict(d):
    for k, v in d.items():
        if isinstance(v, dict):
            d[k] = ddict2dict(v)
    return dict(d)

myddict = ddict()

myddict["a"]["b"]["c"] = "value"

print(myddict)

mydict = ddict2dict(myddict)

print(mydict)