Python Program to create a sub-dictionary containing all keys from dictionary list

Given the dictionary list, our task is to create a new dictionary list that contains all the keys, if not, then assign None to the key and persist of each dictionary.

Example:

Input : test_list = [{‘gfg’ : 3, ‘is’ : 7}, {‘gfg’ : 3, ‘is’ : 1, ‘best’ : 5}, {‘gfg’ : 8}]
Output : [{‘is’: 7, ‘best’: None, ‘gfg’: 3}, {‘is’: 1, ‘best’: 5, ‘gfg’: 3}, {‘is’: None, ‘best’: None, ‘gfg’: 8}]
Explanation : The items with “is” and “best” are added to all lists, wherever missing as None if no values populated.

Input : test_list = [{‘gfg’ : 3}, {‘gfg’ : 3, ‘best’ : 5}, {‘gfg’ : 8}]
Output : [{‘best’: None, ‘gfg’: 3}, {‘best’: 5, ‘gfg’: 3}, {‘best’: None, ‘gfg’: 8}]
Explanation : The items with “best” are added to all lists, wherever missing as None if no values populated.

In this, we perform the task of getting all the required keys using set() and chain.from_iterable(). The next step is to update all the dictionaries with not found keys using list comprehension and get().

Python3




# Python3 code to demonstrate working of
# Ensure all keys in dictionary list
# Using set() + chain.from_iterable() + get() + list comprehension
from itertools import chain
 
# initializing list
test_list = [{'gfg': 3, 'is': 7},
             {'gfg': 3, 'is': 1, 'best': 5},
             {'gfg': 8}]
 
# printing original list
print("The original list is : " + str(test_list))
 
# extracting all keys
all_keys = set(chain.from_iterable(test_list))
 
# assigning None using get() if key's value is not found
res = [dict((key, sub.get(key, None)) for key in all_keys)
       for sub in test_list]
 
# printing result
print("Reformed dictionaries list : " + str(res))


Output:

The original list is : [{‘gfg’: 3, ‘is’: 7}, {‘gfg’: 3, ‘is’: 1, ‘best’: 5}, {‘gfg’: 8}]

Reformed dictionaries list : [{‘gfg’: 3, ‘best’: None, ‘is’: 7}, {‘gfg’: 3, ‘best’: 5, ‘is’: 1}, {‘gfg’: 8, ‘best’: None, ‘is’: None}]

Time Complexity: O(n)
Auxiliary Space: O(n)

Method #2 : Using set() + chain.from_iterable() + update()

In this, the updation and checking of all the keys from dictionary is done using update(), rest all the functions remain similar. 

Step-by-step approach:

  • Import the required modules: chain from the itertools module.
  • Initialize a list of dictionaries named test_list with some sample data.
  • Print the original list using the print() function.
  • Use the chain.from_iterable() function to flatten the list of dictionaries into a single iterable.
  • Convert the iterable into a set using the set() function, to obtain all the unique keys in the list of dictionaries, and store them in the variable all_keys.
  • Iterate over each dictionary in test_list using a for loop.
    • Use the update() method to add a new key-value pair to each dictionary for each key in all_keys that is not already in the current dictionary. The new value assigned is None.
  • Print the updated list of dictionaries using the print() function.

Below is the implementation of the above approach:

Python3




# Python3 code to demonstrate working of
# Ensure all keys in dictionary list
# Using set() + chain.from_iterable() + update()
from itertools import chain
 
# initializing list
test_list = [{'gfg': 3, 'is': 7},
             {'gfg': 3, 'is': 1, 'best': 5},
             {'gfg': 8}]
 
# printing original list
print("The original list is : " + str(test_list))
 
# extracting all keys
all_keys = set(chain.from_iterable(test_list))
 
# assigning None using update() if key is not found
for sub in test_list:
    sub.update({key: None for key in all_keys if key not in sub})
 
# printing result
print("Reformed dictionaries list : " + str(test_list))


Output:

The original list is : [{‘gfg’: 3, ‘is’: 7}, {‘gfg’: 3, ‘is’: 1, ‘best’: 5}, {‘gfg’: 8}]

Reformed dictionaries list : [{‘gfg’: 3, ‘best’: None, ‘is’: 7}, {‘gfg’: 3, ‘best’: 5, ‘is’: 1}, {‘gfg’: 8, ‘best’: None, ‘is’: None}]

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

Method 3 : set() + dictionary comprehension

Step-by-step approach:

  • First, initialize the test_list with some dictionaries.
  • Extract all the keys from the dictionaries using set() and for loop in a generator expression.
  • Create a new list of dictionaries using dictionary comprehension. For each dictionary in test_list, we iterate over all the keys in all_keys and use the get() method to retrieve the value for that key. If the key is missing, we assign None to it.
  • Finally, print the resulting list of dictionaries.

Below is the implementation of the above approach:

Python3




# Python3 code to demonstrate working of
# Ensure all keys in dictionary list
# Using dictionary comprehension
 
# initializing list
test_list = [{'gfg': 3, 'is': 7},
             {'gfg': 3, 'is': 1, 'best': 5},
             {'gfg': 8}]
 
# printing original list
print("The original list is : " + str(test_list))
 
# extracting all keys
all_keys = set(key for d in test_list for key in d)
 
# adding None for missing keys using dictionary comprehension
test_list = [{key: sub.get(key, None) for key in all_keys}
             for sub in test_list]
 
# printing result
print("Reformed dictionaries list : " + str(test_list))


Output

The original list is : [{'gfg': 3, 'is': 7}, {'gfg': 3, 'is': 1, 'best': 5}, {'gfg': 8}]
Reformed dictionaries list : [{'is': 7, 'best': None, 'gfg': 3}, {'is': 1, 'best': 5, 'gfg': 3}, {'is': None, 'best': None, 'gfg': 8}]

Time complexity: O(nm), where n is the length of test_list and m is the average number of keys per dictionary.
Auxiliary space: O(nm), since we create a new list of dictionaries with the same number of elements as test_list, and each dictionary can have up to m keys.

Method 4: Using zip() and dict() constructor

  1. Use the zip() function to transpose test_list into a list of tuples, where each tuple contains the values for each key.
  2. Use the set() function to get all unique keys from test_list.
  3. Initialize a list of dictionaries test_list_dict with the same number of dictionaries as in test_list, but with all values set to None.
  4. Use a for loop to iterate through the tuples of values and keys simultaneously.
  5. Use the dict() constructor to create a new dictionary with the values and keys from each tuple, and update the corresponding dictionary in test_list_dict.
  6. Return test_list_dict.

Python3




# Python3 code to demonstrate working of
# Ensure all keys in dictionary list
# Using zip() and dict() constructor
 
# initializing list
test_list = [{'gfg': 3, 'is': 7},
             {'gfg': 3, 'is': 1, 'best': 5},
             {'gfg': 8}]
 
# printing original list
print("The original list is : " + str(test_list))
 
# using zip() and dict() constructor to add None for missing keys
test_list_dict = [dict(zip(set(key for d in test_list for key in d), [
                       None]*len(set(key for d in test_list for key in d)))) for i in range(len(test_list))]
for values, d in zip(test_list, test_list_dict):
    d.update(values)
 
# printing result
print("Reformed dictionaries list : " + str(test_list_dict))


Output

The original list is : [{'gfg': 3, 'is': 7}, {'gfg': 3, 'is': 1, 'best': 5}, {'gfg': 8}]
Reformed dictionaries list : [{'is': 7, 'best': None, 'gfg': 3}, {'is': 1, 'best': 5, 'gfg': 3}, {'is': None, 'best': None, 'gfg': 8}]

Time complexity: O(NK), where n is the number of dictionaries in test_list and k is the average number of keys per dictionary.
Auxiliary space: O(k), where k is the total number of unique keys in test_list.

Method 5: Using defaultdict(): The idea is to use defaultdict() from the collections module to create a new dictionary with the default value None and then update it with the key-value pairs from the original dictionaries. Below are the steps:

  1. Import the collections module.
  2. Initialize a defaultdict object with default value None.
  3. Loop over each dictionary in the list and update the defaultdict with its key-value pairs using the update() method.
  4. Convert the defaultdict to a regular dictionary using the dict() constructor.
  5. Append the resulting dictionary to a new list.
  6. Print the final list.

Below is the implementation of the above approach:

Python3




from collections import defaultdict
 
# Initialize the list
test_list = [{'gfg': 3, 'is': 7},
             {'gfg': 3, 'is': 1, 'best': 5},
             {'gfg': 8}]
 
# Print original list
print("The original list is : " + str(test_list))
 
# Use defaultdict() to add None for
# missing keys
default_dict = defaultdict(lambda: None)
result_list = []
for d in test_list:
    default_dict.update(d)
    result_list.append(dict(default_dict))
 
# Print the result
print("Reformed dictionaries list : " + str(result_list))


Output

The original list is : [{'gfg': 3, 'is': 7}, {'gfg': 3, 'is': 1, 'best': 5}, {'gfg': 8}]
Reformed dictionaries list : [{'gfg': 3, 'is': 7}, {'gfg': 3, 'is': 1, 'best': 5}, {'gfg': 8, 'is': 1, 'best': 5}]

Time Complexity: O(N*M), where N is the number of dictionaries in the list and M is the maximum number of keys in any dictionary.
Auxiliary space: O(M), where M is the maximum number of keys in any dictionary.