Open In App

Python – Nested Dictionary values summation

Sometimes, while working with Python dictionaries, we can have problem in which we have nested records and we need cumulative summation of it’s keys values. This can have possible application in domains such as web development and competitive programming. Lets discuss certain ways in which this task can be performed. 

Method #1 : Using loop + items() + values() The combination of above functionalities can be used to solve this problem. In this, we iterate through all the values extracted using values() and perform the task of summation. 



Step-by-step approach:

Below is the implementation of the above approach:






# Python3 code to demonstrate working of
# Nested Dictionary values summation
# Using loop + items() + values()
 
# initializing dictionary
test_dict = {'gfg' : {'a' : 4, 'b' : 5, 'c' : 8},
             'is' : {'a' : 8, 'c' : 10},
             'best' : {'c' : 19, 'b' : 10}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# Nested Dictionary values summation
# Using loop + items() + values()
res = dict()
for sub in test_dict.values():
    for key, ele in sub.items():
        res[key] = ele + res.get(key, 0)
 
# printing result
print("The summation dictionary is : " + str(res))

Output : 

The original dictionary is : {‘gfg’: {‘a’: 4, ‘b’: 5, ‘c’: 8}, ‘best’: {‘b’: 10, ‘c’: 19}, ‘is’: {‘a’: 8, ‘c’: 10}} The summation dictionary is : {‘a’: 12, ‘b’: 15, ‘c’: 37}

Time complexity: O(n*m).
Auxiliary space: O(m).

Method #2 : Using Counter() + values() The combination of above methods can be used to perform this task. In this, we save the required frequency using Counter() and extraction of values can be done using values().  Method #2 : Using Counter() + values() Th




# Python3 code to demonstrate working of
# Nested Dictionary values summation
# Using Counter() + values()
from collections import Counter
 
# initializing dictionary
test_dict = {'gfg' : {'a' : 4, 'b' : 5, 'c' : 8},
             'is' : {'a' : 8, 'c' : 10},
             'best' : {'c' : 19, 'b' : 10}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# Nested Dictionary values summation
# Using Counter() + values()
res = Counter()
for val in test_dict.values():
    res.update(val)
     
# printing result
print("The summation dictionary is : " + str(dict(res)))

Output : 

The original dictionary is : {‘gfg’: {‘a’: 4, ‘b’: 5, ‘c’: 8}, ‘best’: {‘b’: 10, ‘c’: 19}, ‘is’: {‘a’: 8, ‘c’: 10}} The summation dictionary is : {‘a’: 12, ‘b’: 15, ‘c’: 37}

Time complexity: O(NM), where N is the number of keys in the outer dictionary and M is the number of keys in the inner dictionaries. This is because we are iterating over each inner dictionary for each outer dictionary key.
Auxiliary space: O(NM), as we are creating a Counter object to store the summation of values from the inner dictionaries. This object will have an entry for each unique key in the inner dictionaries, which can be at most N*M.

Method #3 : Using dictionary comprehension and sum(): 

Algorithm:

1.Initialize the dictionary ‘test_dict’.
2.Using dictionary comprehension and sum(), find the summation of all values for each unique key present in all the nested dictionaries.
3.Store the result in the dictionary ‘res’.
4.Print the original dictionary ‘test_dict’ and the summation dictionary ‘res’.




# initializing dictionary
test_dict = {'gfg' : {'a' : 4, 'b' : 5, 'c' : 8},
             'is' : {'a' : 8, 'c' : 10},
             'best' : {'c' : 19, 'b' : 10}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# Nested Dictionary values summation
# Using dictionary comprehension and sum()
res = {key: sum(d.get(key, 0) for d in test_dict.values()) for key in set().union(*test_dict.values())}
 
# printing result
print("The summation dictionary is : " + str(res))
#This code is contributed by Jyothi pinjala.

Output
The original dictionary is : {'gfg': {'a': 4, 'b': 5, 'c': 8}, 'is': {'a': 8, 'c': 10}, 'best': {'c': 19, 'b': 10}}
The summation dictionary is : {'b': 15, 'a': 12, 'c': 37}

Time Complexity: O(n).
In the worst case, the algorithm iterates through all the keys and values of the nested dictionaries twice, which gives us a time complexity of O(n*m), where n is the number of outer keys and m is the number of inner keys. But since we are using dictionary comprehension and sum(), the time complexity can be considered as O(n).

Auxiliary Space: O(k)
The algorithm uses two dictionaries, ‘test_dict’ and ‘res’, which store the original dictionary and the result respectively. The space used is proportional to the number of unique keys present in all the nested dictionaries. Hence the space complexity can be considered as O(k), where k is the number of unique keys present in all the nested dictionaries.

Method #4: Using defaultdict

Use the defaultdict from the collections module to simplify the code for nested dictionary values summation

Step-by-step approach:

Below is the implementation of the above approach:




# importing defaultdict from collections module
from collections import defaultdict
 
# initializing dictionary
test_dict = {'gfg': {'a': 4, 'b': 5, 'c': 8},
             'is': {'a': 8, 'c': 10},
             'best': {'c': 19, 'b': 10}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# Nested Dictionary values summation
# Using defaultdict
res = defaultdict(int)
 
for inner_dict in test_dict.values():
    for key, value in inner_dict.items():
        res[key] += value
 
# converting defaultdict to dictionary
res = dict(res)
 
# printing result
print("The summation dictionary is : " + str(res))

Output
The original dictionary is : {'gfg': {'a': 4, 'b': 5, 'c': 8}, 'is': {'a': 8, 'c': 10}, 'best': {'c': 19, 'b': 10}}
The summation dictionary is : {'a': 12, 'b': 15, 'c': 37}

Time complexity: O(nm), where n is the number of keys in the outer dictionary and m is the number of keys in the largest inner dictionary.
Auxiliary space: O(k), where k is the number of unique keys in the nested dictionaries. 

Method #5: Using itertools.chain() and collections.defaultdict()

Use itertools.chain() to flatten the nested dictionary into a single iterable, and then use collections.defaultdict() to create a dictionary with default value as 0. Then iterate over the flattened iterable and add the values to the corresponding keys in the defaultdict.

Step-by-step approach:

Below is the implementation of the above approach:




import itertools
import collections
 
# initializing dictionary
test_dict = {'gfg' : {'a' : 4, 'b' : 5, 'c' : 8},
             'is' : {'a' : 8, 'c' : 10},
             'best' : {'c' : 19, 'b' : 10}}
 
# printing original dictionary
print("The original dictionary is : " + str(test_dict))
 
# Nested Dictionary values summation
# Using itertools.chain() and collections.defaultdict()
res = collections.defaultdict(int)
for key, sub_dict in test_dict.items():
    for k, v in sub_dict.items():
        res[k] += v
 
# printing result
print("The summation dictionary is : " + str(dict(res)))

Output
The original dictionary is : {'gfg': {'a': 4, 'b': 5, 'c': 8}, 'is': {'a': 8, 'c': 10}, 'best': {'c': 19, 'b': 10}}
The summation dictionary is : {'a': 12, 'b': 15, 'c': 37}

Time complexity: O(n*m), where n is the number of keys in the outer dictionary and m is the maximum number of keys in the inner dictionaries.
Auxiliary space: O(n), to store the defaultdict.


Article Tags :