简体   繁体   中英

How to dynamically extract key and value from nested dictionary?

I am struggling with how to dynamically extract values from a dictionary record and I am hoping if someone can help.

Here's what my dictionary record looks like from a system API.

from collections import OrderedDict

OrderedDict([('Id', '0061J00000QPnGoQAL'),
             ('Name', 'Acme X-Author RenewalSep tx'),
             ('Account',
              OrderedDict([('Region__c', 'Americas'), ('Name', 'Accenture')])),
             ('CreatedBy', OrderedDict([('Name', 'Jerret Moz')]))])

And my goal here is to make the dictionary record looks like

OrderedDict([('Id', '0061J00000QPnGoQAL'),
             ('Name', 'Acme X-Author'),
             ('Region__c', 'Americas'), 
             ('Name', 'Accenture'),
             ('Name', 'Jerret Moz')])

If even more ideally but not sure if possible

 OrderedDict([('Id', '0061J00000QPnGoQAL'),
              ('Name', 'Acme X-Author'),
              ('Account.Region__c', 'Americas'), 
              ('Account.Name', 'Accenture'),
              ('CreatedBy.Name', 'Jerret Moz')])

Any help or advice is appreciated! Thanks.

You're question is fairly unclear. Especially when it comes to what input you're going to have. Thus the answer below works for the input you provided, but you will probably need to adapt the conditons, splits, and others aspects to your needs.

Your input:

from collections import OrderedDict

D = OrderedDict([('Id', '0061J00000QPnGoQAL'),
             ('Name', 'Acme X-Author RenewalSep tx'),
             ('Account',
              OrderedDict([('Region__c', 'Americas'), ('Name', 'Accenture')])),
             ('CreatedBy', OrderedDict([('Name', 'Jerret Moz')]))])

How to get the second desired output:

D2 = OrderedDict()

for key, value in D.items():
    if key.lower() == "id":
        D2[key] = value
    elif key.lower() == "name":
        D2[key] = value.split(" RenewalSep tx")[0]
    elif type(value) == OrderedDict:
        for key2, value2 in value.items():
            D2[key + "." +  key2] = value2

Output:

OrderedDict([('Id', '0061J00000QPnGoQAL'),
         ('Name', 'Acme X-Author'),
         ('Account.Region__c', 'Americas'),
         ('Account.Name', 'Accenture'),
         ('CreatedBy.Name', 'Jerret Moz')])

Go through the dict, test if the value is a dict, if it is go inside and append.

temp = OrderedDict()

for key,value in dict_name:
    if isinstance(value,dict):
        temp.update(value)

dict_name.update(temp)

You unpack the dictionaries inside into a new OrderedDict and add it to the original OrderedDict

def get_dotted_dict(d, old=""):
    new = OrderedDict()
    for k,v in d.items():
        if isinstance(v, dict):
            for k2, v2 in v.items():
                nk = '.'.join(filter(bool, [old,k,k2]))
                new[nk] = get_dotted_form(v2, nk) if isinstance(v2, dict) else v2
        else:   
            new[k] = v

    return new

d = OrderedDict([('Id', '0061J00000QPnGoQAL'), ('Name', 'Acme X-Author RenewalSep tx'), ('Account', OrderedDict([('Region__c', 'Americas'), ('Name', 'Accenture')])), ('CreatedBy', OrderedDict([('Name', 'Jerret Moz')]))])
nd = get_dotted_form(d)
print nd
# OrderedDict([('Id', '0061J00000QPnGoQAL'), ('Name', 'Acme X-Author RenewalSep tx'), ('Account.Region__c', 'Americas'), ('Account.Name', 'Accenture'), ('CreatedBy.Name', 'Jerret Moz')])

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