简体   繁体   中英

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 .

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 . 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. 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 ?

The .update() method returns None , because it alters the affected dictionary in-place. .pop() does return the popped value, the nested dictionary.

You are updating the contained dict , why not update the parent dict instead?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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