Python:将defaultdict转换为dict

use*_*464 72 python defaultdict

我怎样才能转换defaultdict

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

成为一个普通的词典?

{'2': ['a'], '3': ['b'], '1': ['b', 'a']}
Run Code Online (Sandbox Code Playgroud)

DSM*_*DSM 97

你可以简单地打电话dict:

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

但请记住,defaultdict 一个字典:

>>> isinstance(a, dict)
True
Run Code Online (Sandbox Code Playgroud)

只是略有不同的行为,因为当你尝试访问一个缺少的密钥 - 通常会引发一个KeyError- 时会default_factory被调用:

>>> a.default_factory
<type 'list'>
Run Code Online (Sandbox Code Playgroud)

这就是你print a在字典数据面出现之前所看到的.

因此,在没有实际创建新对象的情况下获得更多类似行为的另一个技巧是重置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
Run Code Online (Sandbox Code Playgroud)

但大多数时候这不值得麻烦.

  • @ user2988464:您已经使用了`default_factory` - 这是你当你在第一时间做出了`defaultdict`,像`defaultdict(INT)`或`defaultdict(名单)`传递的功能.每当你尝试查找的关键在字典中,像'一["3"]',例如,在一般词典你要么值或者它提出了一个'KeyError`例外(如错误,告诉你它找不到那个钥匙).但在`defaultdict`,它改为调用`default_factory`功能*作*新的默认值(这是在'defaultdict`"默认")为您服务. (4认同)
  • 有用的注释是,Django的.items模板属性无法与defaultdict一起使用,这就是为什么我在这里结束了!因此,进行转换有一个很好的理由 (2认同)
  • 还应注意,`pickle`(用于将python对象保存到文件中)在[许多情况下](http://stackoverflow.com/a/16439720/420867)无法处理defaultdict。 (2认同)

Meo*_*eow 24

如果以递归方式定义defaultdict,例如:

from collections import defaultdict
recurddict = lambda: defaultdict(recurddict)
data = recurddict()
data["hello"] = "world"
data["good"]["day"] = True
Run Code Online (Sandbox Code Playgroud)

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

import json
data = json.loads(json.dumps(data))
Run Code Online (Sandbox Code Playgroud)

当然,你的defaultdict中满足的值需要限制在json支持的数据类型中,但如果你不打算在dict中存储类或函数,它应该不是问题.

  • 好主意,太糟糕我的数据不会序列化为JSON:*( (5认同)

whi*_*cko 11

如果您甚至想要一个递归版本来将递归转换defaultdict为a,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)
Run Code Online (Sandbox Code Playgroud)

  • 好一个。如果字典理解只有两层深(即“defaultdict(lambda: defaultdict(int))”),那么使用字典理解是简洁的:“{k: dict(v) for k, v in foo.items()}” (2认同)