Python:将defaultdict转换为dict


90

我如何转换defaultdict

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

成为普通命令?

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

10
dict(number_to_letter)
蒂姆·彼得斯

2
@TimPeters,因为这实际上是一个写得很好的问题,标题很明显(并且应该很容易出现在搜索中),以备将来参考,如果我们找不到更好的骗子,则可以将其作为答案。 。
乔恩·克莱门茨

这个答案应该有所帮助:stackoverflow.com/a/3031915/1628832
karthikr 2013年

1
@JonClements,很好,但是DSM已经做到了-我希望他的回答可以被接受:-)
Tim Peters

2
@TimPeters恭喜10k btw ...我觉得这不会花你很长时间-您应该(无耻的插件)在某个时候通过chat.stackoverflow.com/rooms/6/python弹出:)
Jon Clements

Answers:


121

您可以简单地致电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在字典的数据端出现之前看到的内容。

因此,在没有实际制作新对象的情况下恢复更多类似dict的行为的另一个技巧是重置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

但这在大多数情况下都不值得。


我刚刚开始学习使用Python编程。您能解释一下如何使用default_factory吗?我只是不知道发生了什么事。抱歉。
user2988464 2013年

什么是“ KeyError”?
user2988464 2013年

4
@ user2988464:您已经使用过default_factory-这是您defaultdict第一次制作时传递的函数,例如defaultdict(int)defaultdict(list)。每当您尝试在字典中查找某个键(例如)时a['3'],例如,在普通字典中,您要么获取值,要么引发KeyError异常(例如错误,告诉您找不到该键)。但是,在中defaultdict,它改为调用default_factory函数为您创建一个新的默认值(即中的“默认值” defaultdict)。
DSM

2
有用的注释是,Django的.items模板属性不能与defaultdict一起使用,这就是为什么我在这里结束了!所以这是一个很好的理由转换

2
注意在许多情况下pickle(用于将python对象保存到文件中)不能处理,这也很有帮助。defaultdict
drevicko 2014年

28

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

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

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

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

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


8
好主意,太糟糕了,我的数据不会序列化为JSON:*(
Kasapo

15

如果你连想一个递归版本的递归转换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)

那正是我所需要的!不幸的是,我的defaultdict有一些没有自定义编码器就无法JSON序列化的键(这些键是元组-不是我的选择,这只是我的问题)
Kasapo

好一个 如果只有两层深度(即defaultdict(lambda: defaultdict(int))),则使用字典理解是简洁的: {k: dict(v) for k, v in foo.items()}
ggorlen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.