Home > database >  update dictionary in nested loop
update dictionary in nested loop

Time:11-24

I am having trouble updating a dictionary. i am just extracting certain fields within each key - but the output is not as expected. data, expected output and code are below. Thanks for looking, i appreciate any comments

categories = {'categories_a1' : [{'group': '13GH9', 'number': '1'},{'group': '17KPO', 'number': '73'}, {'group': '26BN11', 'number': '2'}, {'group': '813W', 'number': '99'}],
              'categories_a2' : [{'group': '99ITY', 'number': '12'},{'group': 'JH871', 'number': '15'}, {'group': 'OLH83', 'number': '99'}, {'group': '44RTQ', 'number': '1'}]} 

xpected= {'categories_a1' : [{'13GH9': '1'},{'17KPO':'73'}, {'26BN11':'2'}, {'813W': '99'}],
              'categories_a2' : [{'99ITY':'12'},{'JH871': '15'}, {'OLH83': '99'}, {'44RTQ':'1'}]} 
        

out={}
for k in categories.keys():
    for i in categories[k]:
        x = {k: v for k, v in zip([i['group']], [i['number']])}
    out[k] = x
out.update(out)

CodePudding user response:

One approach:

for key, value in categories.items():
    categories[key] = [{ d["group"] : d["number"] }  for d in value]

print(categories)

Output

{'categories_a1': [{'13GH9': '1'}, {'17KPO': '73'}, {'26BN11': '2'}, {'813W': '99'}], 'categories_a2': [{'99ITY': '12'}, {'JH871': '15'}, {'OLH83': '99'}, {'44RTQ': '1'}]}

CodePudding user response:

Let's first clean up some general weirdness:

out.update(out)

This line does effectively nothing and should be omitted.

x = {k: v for k, v in zip([i['group']], [i['number']])}

This makes little sense; we create lists with one element each and iterate over them in parallel. We could just as easily just use those values directly: x = {i['group']: i['number']}.

After swapping that in, let's consider the part that causes the actual problem:

for i in categories[k]:
    x = {i['group']: i['number']}
out[k] = x

The problem here is that you want out[k] to constitute a list of all of the modified dictionaries, but x is repeatedly being assigned one of those dictionaries, and the result then becomes out[k]. What you presumably intended to do is repeatedly append those dictionaries to a new empty list:

x = []
for i in categories[k]:
    x.append({i['group']: i['number']})
out[k] = x

However, it's clear that you're already familiar and comfortable with comprehensions, and this is an ideal place to use one:

out[k] = [{i['group']: i['number']} for i in categories[k]]

And, of course, we can extend this technique to the overall loop:

out = {
    k: [{i['group']: i['number']} for i in v]
    for k, v in categories.items()
}

Please carefully study the structure of this code and make sure you understand the technique. We have a source dictionary that we want to transform to create our output, and the rule is: the key remains unchanged, the value (which is a list) undergoes its own transformation. So we start by writing the skeleton for a dict comprehension, using .items() to give us key-value pairs:

out = {
    k: # we need to fill in something to do with `v` here
    for k, v in categories.items()
}

Then we figure out what we're doing with the value: each element of the list is a dictionary; the way that we process the list is iterative (each element of the input list tells us an element to use in the output list), but the processing of those elements is not (we look at exactly two hard-coded values from that dict, and make a dict from them). Given an element i of the list, the corresponding dict that we want has exactly one key-value pair, which we can compute as {i['group']: i['number']}. So we wrap a list comprehension around that: [{i['group']: i['number']} for i in v]; and we insert that into the dict comprehension skeleton, giving us the final result.

  • Related