首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将违约的违约(违约)转换为对(违约)的违约?

如何将违约的违约(违约)转换为对(违约)的违约?
EN

Stack Overflow用户
提问于 2014-10-21 21:38:39
回答 2查看 9.7K关注 0票数 31

使用this answer,我创建了一个defaultdict of defaultdict,现在,我想将这个深层次嵌套的dict对象转换回一个普通的python。

代码语言:javascript
复制
from collections import defaultdict

factory = lambda: defaultdict(factory)
defdict = factory()
defdict['one']['two']['three']['four'] = 5

# defaultdict(<function <lambda> at 0x10886f0c8>, {
#             'one': defaultdict(<function <lambda> at 0x10886f0c8>, {
#                 'two': defaultdict(<function <lambda> at 0x10886f0c8>, {
#                     'three': defaultdict(<function <lambda> at 0x10886f0c8>, {
#                         'four': 5})})})})

我认为这不是正确的解决办法:

代码语言:javascript
复制
import json

regdict = json.loads(json.dumps(defdict))

# {u'one': {u'two': {u'three': {u'four': 5}}}}

而且,this answer是不够的,因为它不递归嵌套的dict(s)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-21 21:43:51

您可以在树上递归,将每个defaultdict实例替换为由dict理解生成的dict:

代码语言:javascript
复制
def default_to_regular(d):
    if isinstance(d, defaultdict):
        d = {k: default_to_regular(v) for k, v in d.items()}
    return d

演示:

代码语言:javascript
复制
>>> from collections import defaultdict
>>> factory = lambda: defaultdict(factory)
>>> defdict = factory()
>>> defdict['one']['two']['three']['four'] = 5
>>> defdict
defaultdict(<function <lambda> at 0x103098ed8>, {'one': defaultdict(<function <lambda> at 0x103098ed8>, {'two': defaultdict(<function <lambda> at 0x103098ed8>, {'three': defaultdict(<function <lambda> at 0x103098ed8>, {'four': 5})})})})
>>> default_to_regular(defdict)
{'one': {'two': {'three': {'four': 5}}}}
票数 51
EN

Stack Overflow用户

发布于 2014-10-21 21:58:15

您的actually trying to do是对递归defaultdict进行筛选。而且你也不在乎在不腌制的时候,你是要拿回dict还是defaultdict

虽然有很多方法可以解决这个问题(例如,使用自己的泡菜创建一个defaultdict子类,或者使用copyreg显式地覆盖默认的子类),但是有一种方法非常简单。

注意当您尝试这个错误时,您会注意到:

代码语言:javascript
复制
>>> pickle.dumps(defdict)
PicklingError: Can't pickle <function <lambda> at 0x10d7f4c80>: attribute lookup <lambda> on __main__ failed

您不能对lambda-defined函数进行筛选,因为它们是匿名的,这意味着它们不可能不被加密。

但是从字面上讲,这个函数没有理由需要由lambda来定义。特别是,您甚至不希望它是匿名的,因为您正在显式地给它命名。所以:

代码语言:javascript
复制
def factory(): return defaultdict(factory)

你就完蛋了。

在这里,它正在发挥作用:

代码语言:javascript
复制
>>> from collections import defaultdict
>>> def factory(): return defaultdict(factory)
>>> defdict = factory()
>>> defdict['one']['two']['three']['four'] = 5
>>> import pickle
>>> pickle.dumps(defdict)
b'\x80\x03ccollections\ndefaultdict\nq\x00c__main__\nfactory\nq\x01\x85q\x02Rq\x03X\x03\x00\x00\x00oneq\x04h\x00h\x01\x85q\x05Rq\x06X\x03\x00\x00\x00twoq\x07h\x00h\x01\x85q\x08Rq\tX\x05\x00\x00\x00threeq\nh\x00h\x01\x85q\x0bRq\x0cX\x04\x00\x00\x00fourq\rK\x05ssss.'

还有一些情况是,使用lambda而不是def会造成问题--在运行时您不能同时检查您的函数,调试器中会出现更糟糕的跟踪,等等。如果您想要一个固有的匿名函数,或者一个您可以在表达式中间定义的函数,但是不要使用它来保存输入的三个字符,那么就使用lambda

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26496831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档