Working with Dictionaries in Python

Introduction

In this article we will learn about how we can work with Dictionaries that can enhance your understanding and effective use of this powerful data structure, Dictionaries are one of the most widely used data structures in Python. They store key-value pairs, allowing you to associate values with unique keys. While dictionaries are commonly used for simple data storage and retrieval, they have several interesting features and capabilities.

Dictionaries are Unordered

Unlike lists or tuples, which maintain the order of their elements, dictionaries in Python are unordered collections. This means that the order in which you insert key-value pairs is not guaranteed to be preserved.

my_dict = {'apple': 1, 'banana': 2, 'orange': 3}
print(my_dict)  
# Output: {'apple': 1, 'banana': 2, 'orange': 3}

Immutable Keys

In Python, dictionary keys must be immutable objects, which means their values cannot be changed after creation. Common immutable types used as keys include strings, numbers, and tuples (as long as they contain only immutable objects). This restriction ensures that the hash value of a key remains constant, allowing efficient retrieval of values.

my_dict = {1: 'one', 2: 'two', (1, 2, 3): 'tuple'}
# Valid keys: integers, floats, tuples with immutable elements

# Invalid key: list (mutable)
my_dict = {[1, 2, 3]: 'list'}  # This will raise a TypeError: unhashable type: 'list'

Dictionaries Can Contain Heterogeneous Data

One interesting aspect of dictionaries is that they can store values of different data types within the same dictionary. This flexibility allows you to create complex data structures by nesting other data types, such as lists, tuples, or even other dictionaries, as values.

my_dict = {
    'name': 'Loki',
    'age': 25,
    'grades': [88, 92, 89],
    'address': {
        'city': 'Noida',
        'state': 'UP'
    }
}
print(my_dict)

Efficient Lookup

Dictionaries in Python are implemented using a hash table data structure, which provides efficient key-value lookup operations. The average time complexity for retrieving a value from a dictionary is O(1), making dictionaries an excellent choice when you need fast access to data based on unique keys.

large_dict = {i: i ** 2 for i in range(1000000)}
print(large_dict[999999])  # Retrieves the value instantly
#o/P: 999998000001

Used as Caches

Due to their efficient lookup and ability to store heterogeneous data, dictionaries are often used as caches in Python applications. Caching can significantly improve performance by storing and retrieving frequently accessed data.

def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)


# Cache the Fibonacci numbers
fibonacci_cache = {}


def fibonacci_cached(n):
    if n in fibonacci_cache:
        return fibonacci_cache[n]
    else:
        result = fibonacci(n)
        fibonacci_cache[n] = result
        return result


print(fibonacci_cached(10))  # retrieval from the cache

Dictionaries Support Comprehensions

Python offers a syntax for creating dictionaries using comprehensions, similar to list comprehensions. Dictionary comprehensions allow you to create new dictionaries from existing tables in a readable and expressive manner.

numbers = [1, 2, 3, 4, 5]
squared_numbers = {num: num ** 2 for num in numbers}
print(squared_numbers)
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Built-in Methods

Python dictionaries come with several built-in methods that provide useful functionality. Some commonly used methods include keys(), values(), items(), get(), pop(), update(), and clear(). These methods enable you to perform various operations on dictionaries, such as retrieving keys, values, and key-value pairs, removing items, and merging dictionaries.

# Create a dictionary
my_dict = {'apple': 1, 'banana': 2, 'orange': 3, 'date': 4}

# Get a list of keys
keys = list(my_dict.keys())
print("Keys:", keys)  # Output: Keys: ['apple', 'banana', 'orange', 'date']

# Get a list of values
values = list(my_dict.values())
print("Values:", values)  # Output: Values: [1, 2, 3, 4]

# Get a list of key-value pairs
items = list(my_dict.items())
print("Items:", items)  
# Output: Items: [('apple', 1), ('banana', 2), ('orange', 3), ('date', 4)]

# Get a value using the get() method
value = my_dict.get('banana', 'Not found')
print("Value of 'banana':", value)  
# Output: Value of 'banana': 2

# Get a value using the get() method for a non-existent key
value = my_dict.get('orange', 'Not found')
print("Value of 'orange':", value)  
# Output: Value of 'orange': Not found

# Remove and return a key-value pair
item = my_dict.pop('orange')
print("Popped item:", item)  
# Output: Popped item: 3
print("Dictionary after pop:", my_dict)  
# Output: Dictionary after pop: {'apple': 1, 'banana': 2, 'date': 4}

# Update the dictionary with another dictionary
my_dict.update({'grape': 5, 'banana': 6})
print("Dictionary after update:", my_dict)  
# Output: Dictionary after update: {'apple': 1, 'banana': 6, 'date': 4, 'grape': 5}

# Clear the dictionary
my_dict.clear()
print("Dictionary after clear:", my_dict)  
# Output: Dictionary after clear: {}

In the above example, we create a dictionary my_dict and then demonstrate the usage of various built-in methods.

  • keys(): Returns a view object containing the keys of the dictionary.
  • values(): Returns a view object containing the values of the dictionary.
  • items(): Returns a view object containing the key-value pairs of the dictionary as tuples.
  • get(key, default=None): Returns the value associated with the given key. If the key is not found, it returns the default value (or None if not provided).
  • pop(key, default=None): Removes the key-value pair associated with the given key from the dictionary and returns the value. If the key is not found, it returns the default value (or raises a KeyError if not provided).
  • update(other_dict): Updates the dictionary with the key-value pairs from another dictionary. If keys are present in both dictionaries, the values from the other dictionary will overwrite the existing values.
  • clear(): Removes all key-value pairs from the dictionary, leaving it empty.

Summary

Dictionaries in Python are a powerful data structure that offers a wealth of features and capabilities. By understanding these interesting facts and examples, you can leverage dictionaries more effectively in your Python projects, whether for data storage, caching, or building complex data structures. Explore the many possibilities that dictionaries offer and unlock their full potential in your code.


Similar Articles