【问题标题】:How to convert defaultdict to dict?如何将defaultdict转换为dict?
【发布时间】:2013-12-24 02:00:51
【问题描述】:

如何转换defaultdict

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

做一个普通的dict

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

【问题讨论】:

  • dict(number_to_letter)
  • @TimPeters 因为这实际上是一个写得很好的问题,有一个明显的标题(并且应该很容易在搜索中显示),以供将来参考,如果可以的话,值得将其作为答案'找不到更好的骗子......
  • 这个答案应该会有所帮助:stackoverflow.com/a/3031915/1628832
  • @JonClements,好点子,但 DSM 已经做到了 - 我希望他的回答被接受 :-)
  • @TimPeters 恭喜你获得了 10k 顺便说一句...我觉得你不会花很长时间 - 你应该(无耻的插头)在某个时候弹出 chat.stackoverflow.com/rooms/6/python :)

标签: python defaultdict


【解决方案1】:

您可以直接拨打dict:

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

但请记住,默认字典字典:

>>> 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吗?我只是不知道发生了什么。对不起。
  • 什么是'KeyError'?
  • @user2988464:你已经使用了default_factory——这是你在创建defaultdict时传递的函数,比如defaultdict(int)defaultdict(list)。每当您尝试在字典中查找键时,例如a['3'],例如,在普通字典中,您要么获取该值,要么引发KeyError 异常(如错误,告诉您找不到钥匙)。但在defaultdict 中,它改为调用default_factory 函数为您制作一个新的默认值(即defaultdict 中的“默认”)。
  • 有助于注意 Django 的 .items 模板属性不适用于 defaultdict,这就是我最终来到这里的原因!因此,转换有一个很好的理由
  • 还有助于注意pickle(用于将python对象保存到文件)无法处理many circumstances中的defaultdicts。
【解决方案2】:

如果你的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 中存储类或函数,这应该不是问题。

【讨论】:

  • 好主意,可惜我的数据不会序列化为 JSON :*(
【解决方案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)

【讨论】:

  • 这正是我所需要的!不幸的是,我的 defaultdict 有一些键在没有自定义编码器的情况下不能 JSON 序列化(键是元组——不是我的选择,只是我的问题)
  • 好一个。如果字典理解只有两层深(即defaultdict(lambda: defaultdict(int))),则使用字典理解很简洁:{k: dict(v) for k, v in foo.items()}
猜你喜欢
  • 2018-11-16
  • 2014-12-17
  • 1970-01-01
  • 2019-06-04
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多