Python:将defaultdict转换为dict

Python: convert defaultdict to dict

如何转换defaultdict

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

成为普通命令?

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


您可以简单地调用dict

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

但请记住,defaultdict是一个dict:

1
2
>>> isinstance(a, dict)
True

只是行为稍有不同,因为当您尝试访问缺少的键(通常会引发KeyError)时,将改为调用default_factory

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

这是您在字典的数据端出现之前print a所看到的。

因此,在不实际制作新对象的情况下恢复更多类似dict的行为的另一个技巧是重置default_factory

1
2
3
4
5
6
>>> 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

但是在大多数情况下,这样做是不值得的。


如果您的defaultdict是递归定义的,例如:

1
2
3
4
5
from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] ="world"
data["good"]["day"] = True

将defaultdict转换回dict的另一种简单方法是使用json模块

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

当然,defaultdict中包含的值需要限制为json支持的数据类型,但是如果您不打算在dict中存储类或函数,这应该不是问题。


如果您甚至想要将递归defaultdict转换为dict的递归版本,也可以尝试以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /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)