Home > database >  maintain dictionary structure while reducing nested dictionary
maintain dictionary structure while reducing nested dictionary

Time:03-11

I have a list of pairs of nested dict dd and would like to maintain the structure to a list of dictionaries:

dd = [
    [{'id': 'bla',
      'detail': [{'name': 'discard', 'amount': '123'},
                 {'name': 'KEEP_PAIR_1A', 'amount': '2'}]},
     {'id': 'bla2',
      'detail': [{'name': 'discard', 'amount': '123'},
                 {'name': 'KEEP_PAIR_1B', 'amount': '1'}]}
    ],
    [{'id': 'bla3',
      'detail': [{'name': 'discard', 'amount': '123'},
                 {'name': 'KEEP_PAIR_2A', 'amount': '3'}]},
     {'id': 'bla4',
      'detail': [{'name': 'discard', 'amount': '123'},
                 {'name': 'KEEP_PAIR_2B', 'amount': '4'}]}
    ]
]

I want to reduce this to a list of paired dictionaries while extracting only some detail. For example, an expected output may look like this:

[{'name': ['KEEP_PAIR_1A', 'KEEP_PAIR_1B'], 'amount': [2, 1]},
 {'name': ['KEEP_PAIR_2A', 'KEEP_PAIR_2B'], 'amount': [3, 4]}]

I have run my code:

pair=[]
for all_pairs in dd:
    for output_pairs in all_pairs:
        for d in output_pairs.get('detail'):
            if d['name'] != 'discard':
                pair.append(d)
output_pair = {
    k: [d.get(k) for d in pair]
    for k in set().union(*pair)
}

But it didn't maintain that structure :

{'name': ['KEEP_PAIR_1A', 'KEEP_PAIR_1B', 'KEEP_PAIR_2A', 'KEEP_PAIR_2B'],
 'amount': ['2', '1', '3', '4']}
                                                                                                                       

I assume I would need to use some list comprehension to solve this but where in the for loop should I do that to maintain the structure.

CodePudding user response:

Since you want to combine dictionaries in lists, one option is to use dict.setdefault:

pair = []
for all_pairs in dd:
    dct = {}
    for output_pairs in all_pairs:
        for d in output_pairs.get('detail'):
            if d['name'] != 'discard':
                for k,v in d.items():
                    dct.setdefault(k, []).append(v)
    pair.append(dct)

Output:

[{'name': ['KEEP_PAIR_1A', 'KEEP_PAIR_1B'], 'amount': [2, 1]},
 {'name': ['KEEP_PAIR_2A', 'KEEP_PAIR_2B'], 'amount': [3, 4]}]
  • Related