简体   繁体   English

带有dict的Python中的链接方法调用

[英]Chained Method Calls in Python with dict

I needed to flatten a dictionary today. 我今天需要整理一本字典。 Meaning I wanted: 我想要的意思是:

{'_id': 0, 'sub': {'a': 1, 'b':2}}

to become: 成为:

{'_id': 0, 'a':1, 'b':2}

So I thought I could be clever and pull off the following one-liner. 因此,我认为自己会很聪明,然后再完成下面的一线工作。

One-liner: 单线:

x = dict(_id=0, sub=dict(a=1, b=2))
y = x.pop('sub').update(x)  # incorrect result

This results in y = None . 结果y = None

So I obviously resorted to: 因此,我显然采取了以下措施:

Multi-Step: 多重步骤:

x = dict(_id=0, sub=dict(a=1, b=2))
y = x.pop('sub')
y.update(x)   # correct result

Setting "good expressive coding practices" asside for a moment, I would like to understand why the One-liner approach above yields None . 设置“表现良好的编码实践” asside了一会儿,我想明白为什么上述收益率的一个班轮方法None I would have thought that x.pop('sub') would have resulted in a temporary dict on a stack somewhere and the original x dict would be immediately updated. 我本以为x.pop('sub')会导致某个地方的堆栈上出现临时字典,而原始的x字典会立即更新。 Then the stack object would receive the next method in the chain which is the update. 然后,堆栈对象将接收链中的下一个方法,即更新。 This obviously does not seem to be the case. 显然似乎并非如此。

For the communities better understanding (and clearly mine) - how does python resolve the one-liner and result in None ? 为了使社区更好地理解(并且清楚地是我的)-python如何解决一线问题并导致None

The .update() method returns None , because it alters the affected dictionary in-place. .update()方法返回None ,因为它就地更改了受影响的字典。 .pop() does return the popped value, the nested dictionary. .pop()确实返回弹出的值,即嵌套字典。

You are updating the contained dict , why not update the parent dict instead? 您正在更新包含的dict ,为什么不更新 dict呢?

x.update(x.pop('sub'))

Result: 结果:

>>> x = dict(_id=0, sub=dict(a=1, b=2))
>>> x.update(x.pop('sub'))
>>> x
{'a': 1, '_id': 0, 'b': 2}

Or you could do this recursively: 或者,您可以递归地执行此操作:

def inplace_flatten(d):
    keys = list(d.keys())
    for k in keys:
        if isinstance(d[k], dict):
            inplace_flatten(d[k])
            d.update(d.pop(k))

因为y获得dict.update()的结果,所以它为None

This should do the trick 这应该可以解决问题

def flatten(d, answer=None):
    if answer == None:
        answer = {}
    if not d:
        return answer
    else:
        for k in d:
            if isinstance(d[k], dict):
                flatten(d[k], answer)
            else:
                answer[k] = d[k]
        return answer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM