Implementing a Self-Nesting Python Dictionary with Unlimited Depth
83. Custom Dictionary with Default Factory
Write a Python program to create a custom dictionary class that allows for nested dictionary creation on the fly, similar to collections.defaultdict but with unlimited nesting depth.
Solution:
Python Code:
# Define a custom dictionary class that supports nested dictionary creation on the fly.
class NestedDefaultDict:
"""
A custom dictionary class that allows for nested dictionary creation on the fly,
similar to collections.defaultdict but with unlimited nesting depth.
"""
# Initialize the NestedDefaultDict with an empty dictionary to store data.
def __init__(self):
self.data = {}
# Define the behavior for accessing items using the `[]` operator.
def __getitem__(self, key):
# If the key does not exist in the dictionary, create a new NestedDefaultDict for it.
if key not in self.data:
self.data[key] = NestedDefaultDict()
# Return the value associated with the key (either an existing value or a new NestedDefaultDict).
return self.data[key]
# Define the behavior for setting items using the `[]` operator.
def __setitem__(self, key, value):
# Assign the given value to the specified key in the dictionary.
self.data[key] = value
# Define the string representation of the NestedDefaultDict for debugging or printing.
def __repr__(self):
# Return the string representation of the internal dictionary.
return repr(self.data)
# Convert the NestedDefaultDict to a regular dictionary recursively.
def to_dict(self):
"""Convert the NestedDefaultDict to a regular dictionary recursively."""
# Initialize an empty dictionary to store the converted result.
result = {}
# Iterate over each key-value pair in the internal dictionary.
for key, value in self.data.items():
# If the value is another NestedDefaultDict, recursively convert it to a regular dictionary.
if isinstance(value, NestedDefaultDict):
result[key] = value.to_dict()
else:
# Otherwise, directly assign the value to the result dictionary.
result[key] = value
# Return the fully converted regular dictionary.
return result
# Example usage of NestedDefaultDict
# Create an instance of NestedDefaultDict.
nested = NestedDefaultDict()
# Dynamically create nested keys and assign values to them.
# This creates a nested structure: {'users': {'lio': {'profile': {'email': '[email protected]', 'age': 30}}}}
nested['users']['lio']['profile']['email'] = '[email protected]'
nested['users']['lio']['profile']['age'] = 30
# Add another user and their settings dynamically.
# This creates a nested structure: {'users': {'zuzka': {'profile': {'email': '[email protected]'}, 'settings': {'notifications': True}}}}
nested['users']['zuzka']['profile']['email'] = '[email protected]'
nested['users']['zuzka']['settings']['notifications'] = True
# Convert the NestedDefaultDict to a regular dictionary for display purposes.
# The `to_dict` method ensures the nested structure is preserved in a standard dictionary format.
regular_dict = nested.to_dict()
# Print the resulting regular dictionary to verify the structure.
print(regular_dict)
Output:
{'users': {'lio': {'profile': {'email': '[email protected]', 'age': 30}}, 'zuzka': {'profile': {'email': '[email protected]'}, 'settings': {'notifications': True}}}}
Explanation of Each Line:
- Class Definition : Defines a custom class NestedDefaultDict to support dynamic nested dictionary creation.
- Initialization : Initializes the NestedDefaultDict with an empty dictionary (self.data) to store key-value pairs.
- Get Item Behavior : Implements the __getitem__ method to allow accessing keys using []. If a key doesn't exist, it creates a new NestedDefaultDict for that key.
- Set Item Behavior : Implements the __setitem__ method to allow assigning values to keys using [].
- String Representation : Implements the __repr__ method to provide a string representation of the internal dictionary for debugging or printing.
- Recursive Conversion : Implements the to_dict method to recursively convert the NestedDefaultDict into a standard Python dictionary.
- Conversion Logic : Iterates through all key-value pairs in the internal dictionary, converting nested NestedDefaultDict instances into regular dictionaries.
- Example Usage : Demonstrates how to use the NestedDefaultDict class to dynamically create nested structures.
- Dynamic Key Assignment : Assigns values to deeply nested keys without explicitly creating intermediate dictionaries.
- Conversion to Regular Dict : Converts the NestedDefaultDict instance to a standard dictionary using the to_dict method.
- Print Result : Prints the resulting regular dictionary to verify the nested structure.
Explanation - Custom Dictionary with Default Factory
- Concept: Create a dictionary class that automatically creates nested dictionaries of unlimited depth.
- Challenge: Override key dictionary methods to create new dictionary instances on the fly.
- Key Skills:
- Object-oriented programming
- Method overriding
- Recursive data structure design
- Applications:
- Building complex configuration systems
- Creating hierarchical data structures incrementally
- Implementing multi-level caching
- Managing nested settings or preferences
- Benefits:
- Eliminates need for explicit initialization of intermediate dictionaries
- Provides intuitive syntax for nested data access
- Reduces boilerplate code when building complex structures
For more Practice: Solve these Related Problems:
- Write a Python program to create a dictionary that automatically creates missing keys with a default list.
- Write a Python function to convert a JSON object into a deeply nested `defaultdict`.
- Write a Python class that behaves like a dictionary but triggers a callback function whenever a new key is accessed.
- Write a Python function to create a dictionary that tracks the number of times each key is accessed.
Python Code Editor:
Previous: Dictionary-based Memoization.
Next: Dictionary Transformation Pipeline.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.