How to Convert dictionary to K sized dictionaries using Python?


Dictionaries are key-value data structures in python where in the keys are unique and values can be repeated or not. The keys and values can be of any data type. In this article we are going to see How to Convert dictionary to K sized dictionaries using Python which simply means we will divide a dictionary into k-smaller dictionaries where k is any positive number i.e. k>0.

Example

Let the input dictionary be d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'x': 8, 'y': 9}

The corresponding output should be {'a': 1, 'b': 2, 'c': 3}, {'d': 4, 'e': 5, 'f': 6}, {'g': 7, 'x': 8, 'y': 9}

The input dictionary d is of size 9 as there are 9 key-value pairs, we simply divide d into 3 smaller dictionaries each of size 3.

Method 1: Naïve method

Naive methods are generally the simplest or least complex approaches to any given problem statement and shouldn't necessarily be selected as solutions. When applied to dictionary conversion, for example, this could involve iterating over all keys from the original dictionary and dispersing them evenly across K-sized dictionaries using basic index calculations.

Example

def convert_dict_to_k_sized_dicts(dictionary, k):
    result = [{} for _ in range(k)]  # Initialize a list of empty dictionaries    
    keys = list(dictionary.keys())  # Get the keys of the original dictionary
    num_keys = len(keys)    
    for i in range(num_keys):
        key = keys[i]
        value = dictionary[key]    
	      # Determine the index of the dictionary to store the key-value pair    
        index = i % k
        # Add the key-value pair to the respective dictionary          
        result[index][key] = value      
    return result
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7,'x':8,'y':9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'a': 1, 'd': 4, 'g': 7}, {'b': 2, 'e': 5, 'x': 8}, {'c': 3, 'f': 6, 'y': 9}]

Method 2: Using itertools.cycle

The itertools module of python offers a function itertools.cycle() which creates an iterator to cycle indefinitely over the elements of an iterable. When the function is called, it returns an iterator that repeatedly returns elements from the iterable in a circular manner which in simple terms means that once the iterable’s end is reached, it starts over again from the beginning hence allowing us to iterate over elements without manual implementation of looping logic.

The next item in an iterator is fetched using the next() function. The following item in the iterator is returned when an iterator is provided as an argument. The iterator advances with each call to next(), which also returns the next item. Next() is frequently used in loops to traverse through an iterator's items until each one has been handled. Calling next() produces a StopIteration exception, signalling the end of the iteration, when there are no more items in the iterator.

Together, itertools.cycle() and next() can be used to create a circular iteration pattern.

Example

import itertools

def convert_dict_to_k_sized_dicts(dictionary, k):
    result = [{} for _ in range(k)]    
    keys = list(dictionary.keys())
    num_keys = len(keys)    
    key_cycle = itertools.cycle(range(k))
    for i, key in enumerate(keys):
        value = dictionary[key]
        index = next(key_cycle)
        result[index][key] = value    
    return result
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'x': 8, 'y': 9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'a': 1, 'd': 4, 'g': 7}, {'b': 2, 'e': 5, 'x': 8}, {'c': 3, 'f': 6, 'y': 9}]

Method 3: Using dict comprehension and enumerate

Dictionary comprehensions provide an efficient method of creating compact/readable dictionaries in Python, while enumerate() offers an easier means of traversing iterables while keeping track of their index numbers and contents; returning an iterator which yields index/value pairs allows easy access to both elements during iteration.

Example

def convert_dict_to_k_sized_dicts(dictionary, k):
    result = [{} for _ in range(k)]    
    for i, (key, value) in enumerate(dictionary.items()):
        index = i % k
        result[index][key] = value    
    return result

my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'x': 8, 'y': 9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'a': 1, 'd': 4, 'g': 7}, {'b': 2, 'e': 5, 'x': 8}, {'c': 3, 'f': 6, 'y': 9}]

Method 4: Using list comprehension and slicing

By simply defining an expression and iterating over one or more iterables, lists may be created using list comprehensions. In the case at hand, list comprehension is assisting in the generation of a list of dictionaries, each of which is created using a dictionary comprehension that iterates over a subset of the keys and values list that is determined by slicing and aids in selecting elements at k-intervals.

Example

def convert_dict_to_k_sized_dicts(dictionary, k):
    keys = list(dictionary.keys())
    values = list(dictionary.values())
    return [{keys[i]: values[i] for i in range(start, len(keys), k)} for start in range(k)]

my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'x': 8, 'y': 9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'a': 1, 'd': 4, 'g': 7}, {'b': 2, 'e': 5, 'x': 8}, {'c': 3, 'f': 6, 'y': 9}]

Method 5: Using numpy.array_split

An array can be divided into multiple sub-arrays along a specified axis using the data handling module Numpy's array_split() function. An array and the desired number of splits with equal sizes are its inputs, and its output is a list of sub-arrays. Since we will be dividing our dictionary into k equal sections, the function is very helpful in this situation because it eliminates the need for any manual calculations or indexing.

Example

import numpy as np

def convert_dict_to_k_sized_dicts(dictionary, k):
    keys = list(dictionary.keys())
    values = list(dictionary.values())
    result = []
    for group in np.array_split(range(len(keys)), k):
        sub_dict = {keys[i]: values[i] for i in group}
        result.append(sub_dict)
    return result

my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'x': 8, 'y': 9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'a': 1, 'b': 2, 'c': 3}, {'d': 4, 'e': 5, 'f': 6}, {'g': 7, 'x': 8, 'y': 9}]

Method 6: Using zip and unpacking

You can remove components from an iterable or apply variables to a sequence using the unpacking method. With the help of the Python method zip(), several iterables may be efficiently combined into tuples element by element. When combined, the functions zip() and unpacking enable the processing of related items from several iterables at once.

Example

def convert_dict_to_k_sized_dicts(dictionary, k):
    keys = list(dictionary.keys())
    values = list(dictionary.values())
    result = [dict(zip(keys[start::k], values[start::k])) for start in range(k)]
    return result

my_dict = {'abb': 1, 'xyz': 2, 'cat': 3, 'dog': 4, 'elephant': 5, 'frog': 6, 'garlic': 7, 'x': 8, 'y': 9}
k = 3
result = convert_dict_to_k_sized_dicts(my_dict, k)
print(result)

Output

[{'abb': 1, 'dog': 4, 'garlic': 7}, {'xyz': 2, 'elephant': 5, 'x': 8}, {'cat': 3, 'frog': 6, 'y': 9}]

Conclusion

We have covered multiple ways to convert a dictionary into k sized dictionaries in python. These include the naive approach; using itertools.cycle(); employing dictionary comprehension; xenumerate(); utilizing list comprehension and slicing; employing numpy.array_split() and lastly using zip() with unpacking. All the methods have the same time complexity of O(n) where n represents the number of key-value pairs.

Updated on: 29-Aug-2023

48 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements