Prateek Daniels
Prateek Daniels

Reputation: 483

Find the smallest three values in a nested dictionary

I have a nested dictionary ( i.e. sample_dict), where for each day, we need to find the smallest three values (in ascending manner), after which the result has to be stored in a new dictionary.

The sample_dict is as follows:

sample_dict ={ '2020-12-22': {'A': 0.0650,'B': 0.2920, 'C': 0.0780, 'D': 1.28008, 'G': 3.122},
'2020-12-23': {'B': 0.3670, 'C': 0.4890, 'G':1.34235, 'H': 0.227731},
'2020-12-24': {'A': 0.3630, 'B': 0.3960, 'C': 0.0950, 'Z':0.3735},
'2020-12-25': {'C': 0.8366, 'B': 0.4840},
'2020-12-26': {'Y': 5.366}}

The final dictionary (i.e. result) after selecting the smallest three for each date would look like:

enter image description here

Can someone suggest a solution using for loops.

Upvotes: 1

Views: 65

Answers (3)

Caleb McNevin
Caleb McNevin

Reputation: 362

This should work for your purposes.

sample_dict = {'2020-12-22': {'A': 0.0650, 'B': 0.2920, 'C': 0.0780, 'D': 1.28008, 'G': 3.122},
               '2020-12-23': {'B': 0.3670, 'C': 0.4890, 'G':1.34235, 'H': 0.227731},
               '2020-12-24': {'A': 0.3630, 'B': 0.3960, 'C': 0.0950, 'Z':0.3735},
               '2020-12-25': {'C': 0.8366, 'B': 0.4840},
               '2020-12-26': {'Y': 5.366}}    
results_dict = {day[0]:{sample[0]:sample[1] for sample in sorted(day[1].items(), key=lambda e: e[1])[:3]} for day in sample_dict.items()}

# Output
{'2020-12-22': {'A': 0.065, 'B': 0.292, 'C': 0.078},                                                                     
 '2020-12-23': {'B': 0.367, 'C': 0.489, 'H': 0.227731},                                                                  
 '2020-12-24': {'A': 0.363, 'C': 0.095, 'Z': 0.3735},                                                                    
 '2020-12-25': {'B': 0.484, 'C': 0.8366},                                                                                
 '2020-12-26': {'Y': 5.366}}

Upvotes: 1

cs95
cs95

Reputation: 402814

Let's use heapq.nsmallest inside a dictionary comprehension to select the smallest 3 items per subdict:

from operator import itemgetter
import heapq

for k, v in sample_dict.items():
    # Look ma, no `sorted`
    sample_dict[k] = dict(heapq.nsmallest(3, v.items(), key=itemgetter(1)))

print (sample_dict)
# {'2020-12-22': {'A': 0.065, 'C': 0.078, 'B': 0.292}, 
#  '2020-12-23': {'H': 0.227731, 'B': 0.367, 'C': 0.489}, 
#  '2020-12-24': {'C': 0.095, 'A': 0.363, 'Z': 0.3735}, 
#  '2020-12-25': {'B': 0.484, 'C': 0.8366}, 
#  '2020-12-26': {'Y': 5.366}}

This is pretty fast because it does not need to sort the array, and updates sample_dict in-place.

Upvotes: 3

U13-Forward
U13-Forward

Reputation: 71610

Try using this dictionary comprehension:

print({k: dict(sorted(sorted(v.items(), key=lambda x: x[1]), key=lambda x: x[0])[:3]) for k, v in sample_dict.items()})

Output:

{'2020-12-22': {'A': 0.065, 'B': 0.292, 'C': 0.078}, '2020-12-23': {'B': 0.367, 'C': 0.489, 'G': 1.34235}, '2020-12-24': {'A': 0.363, 'B': 0.396, 'C': 0.095}, '2020-12-25': {'B': 0.484, 'C': 0.8366}, '2020-12-26': {'Y': 5.366}}

Upvotes: 1

Related Questions