简体   繁体   中英

Create a new key and assign the value of an existing key in a nested dictionary

This is how the nested dictionary looks like:

mydict = {
    'a1':{
        'x': 1,
        'y': 2
    },
    'a2':{
        'x':3,
        'y':4
    }
}

I am trying to add a new key z in dictionaries a1 and a2 such that the new key contains the value of key x .

Currently, I am using this approach:

for key in mydict:
  mydict[key]['z'] = mydict[key]['x']

Is there any other way to do this?

Nothing wrong with your loop approach. You can be a little more concise iterating over the inner dicts directly:

for d in mydict.values():
    d['z'] = d['x']

You can create your own zdict class! If you are sure that the dict will get a x key at init you can set z at __init__ . Otherwise, you can design you own __getitem__ method to behave as you would like. I provide the two solutions.

class zdict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['z'] = self['x']

class zdict2(dict):
    def __getitem__(self, item):
        if item == 'z':
            return super().__getitem__('x') # note that you can't modify the value of "z" anymore in that implementation but you can figure something to change that
        else:
            return super().__getitem__(item)


mydict = {
    'a1': zdict(
        x=1,
        y=2
    ),
    'a2':zdict(
        x=3,
        y=4
    ),
}

print(mydict['a1']['z'], mydict['a1']['x'])
print(mydict['a2']['z'], mydict['a2']['x'])



mydict2 = {
    'a1': zdict2(
        x=1,
        y=2
    ),
    'a2':zdict2(
        x=3,
        y=4
    ),
}

print(mydict2['a1']['z'], mydict2['a1']['x'])
print(mydict2['a2']['z'], mydict2['a2']['x'])

EDIT1: Not arguing about efficiency here because I have not benchmarked both solutions!


EDIT2: If you want to keep the key 'x' use:

mydict = { k: {'z': v['x'], **v} for k, v in mydict.items() }

No as readable as your solution though I think of it to be more pythonic is this:

mydict = { k: {'z': v.pop('x'), **v} for k, v in mydict.items() }

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