Reputation: 3502
Would anyone be able to give me a tip on how to split a nested dictionary into separate nested dictionaries based on a common key name called score
and the value of score
?
For example break up this nested dictionary nested_group_map_original
:
nested_group_map_original = {
'group_l1n': {'score': 0.12949562072753906, 'VMA-1-1': '14', 'VMA-1-2': '13', 'VMA-1-3': '15', 'VMA-1-4': '11', 'VMA-1-5': '9', 'VMA-1-7': '7', 'VMA-1-10': '21', 'VMA-1-11': '16'},
'group_l1s': {'score': -0.40303707122802734, 'VMA-1-6': '8', 'VMA-1-8': '6', 'VMA-1-9': '10', 'VMA-1-12': '19', 'VMA-1-13': '20', 'VMA-1-14': '37', 'VMA-1-15': '38', 'VMA-1-16': '39'},
'group_l2n': {'score': 0.6091512680053768, 'VAV-2-1': '12032', 'VAV-2-2': '12033', 'VMA-2-3': '31', 'VMA-2-4': '29', 'VAV-2-5': '12028', 'VMA-2-6': '27', 'VMA-2-7': '30', 'VMA-2-12': '26'},
'group_l2s': {'score': 0.11078681945799929, 'VMA-2-8': '34', 'VAV-2-9': '12035', 'VMA-2-10': '36', 'VMA-2-11': '25', 'VMA-2-13': '23', 'VMA-2-14': '24'}
}
Make it look like this below but in a programmatic way for two separate nested dictionaries named nested_group_map_copy_lows
and nested_group_map_copy_high
:
nested_group_map_copy_lows = {
'group_l1s': {'score': -0.40303707122802734, 'VMA-1-6': '8', 'VMA-1-8': '6', 'VMA-1-9': '10', 'VMA-1-12': '19', 'VMA-1-13': '20', 'VMA-1-14': '37', 'VMA-1-15': '38', 'VMA-1-16': '39'},
'group_l2s': {'score': 0.11078681945799929, 'VMA-2-8': '34', 'VAV-2-9': '12035', 'VMA-2-10': '36', 'VMA-2-11': '25', 'VMA-2-13': '23', 'VMA-2-14': '24'}
}
nested_group_map_copy_highs = {
'group_l2n': {'score': 0.6091512680053768, 'VAV-2-1': '12032', 'VAV-2-2': '12033', 'VMA-2-3': '31', 'VMA-2-4': '29', 'VAV-2-5': '12028', 'VMA-2-6': '27', 'VMA-2-7': '30', 'VMA-2-12': '26'},
'group_l1n': {'score': 0.12949562072753906, 'VMA-1-1': '14', 'VMA-1-2': '13', 'VMA-1-3': '15', 'VMA-1-4': '11', 'VMA-1-5': '9', 'VMA-1-7': '7', 'VMA-1-10': '21', 'VMA-1-11': '16'},
}
Not really sure how to tackle this, I think I need to use enumerate
to create entire new dictionaries but if I try to find highest scores in a separate list scores_
scores_ = []
for i in nested_group_map_original:
scores_.append(nested_group_map_original[i]["score"])
scores_sorted = sorted(scores_, key = float)
Then slice for highest and lowest values:
scores_sorted_highs = scores_sorted[2:]
scores_sorted_lows = scores_sorted[:2]
I am stuck here I dont think del
is way to go, any tips greatly appreciated... I know in my code I am not even defining new dictionaries which I think I could do with Python enumerate
but not sure how to implement that
for i in nested_group_map_original:
if nested_group_map_original[i]["score"] in scores_sorted_highs:
del nested_group_map_original[i]
This errors out:
RuntimeError: dictionary changed size during iteration
Upvotes: 1
Views: 329
Reputation: 659
You can sort the keys of the original dictionary according to their corresponding scores, like so:
sorted_keys = sorted(nested_group_map_original, key = lambda x: nested_group_map_original[x]['score'])
You can then split into two different dictionaries according to how many values you want in each. Like in your example of two, you could do the following:
scores_sorted_lows = {k:nested_group_map_original[k] for k in sorted_keys[:2]}
scores_sorted_highs = {k:nested_group_map_original[k] for k in sorted_keys[2:]}
Upvotes: 2
Reputation: 17131
If the dict isn't super huge, then one easy way to do this would just be to construct the list by filtering the map twice using a comprehension:
nested_group_map_low = {k:v for k,v in nested_group_map_original.items() if is_low_score(v["score"])}
nested_group_map_high = {k:v for k,v in nested_group_map_original.items() if not is_low_score(v["score"])}
Upvotes: 0