Artificial Intelligence

Dictionary Python – Great Learning


Dictionaries in Python come super handy as they let you store and organize data in a flexible way. Think of it as a real-life dictionary where you can search for words and find their meanings. With dictionaries, you can associate “keys” with “values.”  The keys are like the words you’re looking up, and the values are the meanings that go along with those words. 

Dictionaries provide fast and efficient data retrieval based on keys. Python uses hashing to quickly locate the value associated with a given key, making dictionaries ideal for accessing specific data quickly. Secondly, dictionaries allow you to organize and structure your data logically. Additionally, you get a concise and readable way to represent complex relationships and mappings between different entities. 

Let’s learn more about creating, accessing, modifying, and updating dictionaries along with their operations and comprehensions. We’ll also learn about nested dictionaries, dictionary manipulation techniques, built-in functions and so much more.

Creating and Accessing Dictionaries

Let’s dive into creating and accessing dictionaries in Python. 

Dictionary Syntax and Structure

Dictionaries are defined using curly braces ({}) and consist of key-value pairs. The key-value pairs are separated by colons (:) and individual pairs are separated by commas. The keys can be any immutable data type, such as strings, numbers, or tuples, while the values can be any data type, including lists, strings, numbers, or even other dictionaries.

Dictionary Creation and Initialization

Let’s say we want to create a dictionary to store the ages of different people. Here’s how to do it:

ages = {"Alice": 25, "Bob": 30, "Charlie": 35}

Here, we have a dictionary called ages with three key-value pairs. The keys are the names of people, and the corresponding values are their ages.

Accessing Values Using Keys

To access the values in a dictionary, you can use the keys as the “index” to retrieve the associated values. Let’s continue with our ages dictionary example:

print(ages["Alice"])  # Output: 25

print(ages["Bob"])    # Output: 30

print(ages["Charlie"])# Output: 35

By using the respective keys in square brackets, we can access the values associated with those keys. In this case, we retrieve the ages of Alice, Bob, and Charlie.

Handling Missing Keys and Default Values

Sometimes, you may need to handle situations where a key doesn’t exist in a dictionary. To avoid errors, you can use the get() method or conditional statements. The get() method allows you to specify a default value to return if the key is not found:

print(ages.get(“Dave”, “Unknown”))  # Output: Unknown

Here, the key “Dave” doesn’t exist in the age dictionary. By using get(), we provide a default value of “Unknown” to be returned instead.

Alternatively, you can use conditional statements to check if a key exists in a dictionary before accessing its value:

if “Alice” in ages:

    print(ages["Alice"])  # Output: 25

else:

    print("Alice's age is not available.")

Here, we check if the key “Alice” is present in the ages dictionary before accessing its value. If the key exists, we print the associated age; otherwise, we display a message indicating that the age is not available.

Modifying and Updating Dictionaries

Let’s learn how to modify and update dictionaries.

Adding and Removing Key-Value Pairs

Dictionaries are mutable, meaning you can modify them by adding or removing key-value pairs. To add a new key-value pair, you can simply assign a value to a new or existing key:

student = {"name": "Alice", "age": 25}

student["grade"] = "A"

Here, we have a dictionary called student with two key-value pairs. We then add a new key called “grade” and assign the value “A” to it. The dictionary now has three key-value pairs.

To remove a key-value pair, you can use the del keyword followed by the dictionary name and the key you want to remove:

del student["age"]

Here, we remove the key “age” and its associated value from the student dictionary. After this, the dictionary only contains the “name” and “grade” key-value pairs.

Updating Values for Existing Keys

If you want to update the value of an existing key in a dictionary, you can simply reassign a new value to that key:

student["grade"] = "A+"

Here, we update the value of the “grade” key to “A+”. The dictionary is modified to reflect the updated value for the key.

Merging Dictionaries using the update() Method

You can merge the contents of two dictionaries into one by using the update() method. Let’s say we have two dictionaries, dict1 and dict2, and we want to merge them into a new dictionary called merged_dict:

dict1 = {"a": 1, "b": 2}

dict2 = {"c": 3, "d": 4}

merged_dict = {}

merged_dict.update(dict1)

merged_dict.update(dict2)

Here, we create an empty dictionary called merged_dict and then use the update() method to add the key-value pairs from dict1 and dict2. After executing this code, merged_dict will contain all the key-value pairs from both dict1 and dict2.

Common Dictionary Operations and Methods

By mastering these common operations and methods, you’ll be equipped to work efficiently with dictionaries in Python. Whether you need to iterate over items, check for key existence, extract keys or values, or find the length of a dictionary, these techniques will prove useful in various programming scenarios.

Iterating over Dictionary Items

It allows you to access both the keys and their corresponding values. You can use a loop, such as a for loop, to iterate over the items. Here’s an example:

student = {"name": "Alice", "age": 25, "grade": "A"}

for key, value in student.items():

    print(key, value)

Here, we iterate over the items of the student dictionary using the items() method. Within the loop, we access each key-value pair and print them. This allows you to perform operations on each item or extract specific information from the dictionary.

Checking for the Existence of Keys

Sometimes, you may need to check if a specific key exists in a dictionary. You can use the in keyword to perform this check. Let’s see an example:

student = {"name": "Alice", "age": 25, "grade": "A"}

if "age" in student:

    print("Age exists in the dictionary.")

else:

    print("Age does not exist in the dictionary.")

Here, we check if the key “age” exists in the student dictionary using the in keyword. If the key is present, we print a message indicating its existence; otherwise, we print a message indicating its absence.

Getting Keys, Values, or Both from a Dictionary

There are useful methods available to extract keys, values, or both from a dictionary. Here are some examples:

student = {"name": "Alice", "age": 25, "grade": "A"}

keys = student.keys()

values = student.values()

items = student.items()

print(keys)   # Output: dict_keys(['name', 'age', 'grade'])

print(values) # Output: dict_values(['Alice', 25, 'A'])

print(items)  # Output: dict_items([('name', 'Alice'), ('age', 25), ('grade', 'A')])

Here, we use the keys(), values(), and items() methods to obtain the keys, values, and key-value pairs as separate objects. These methods return special views that allow you to access the dictionary’s keys, values, or items in a convenient way.

Finding the Length of a Dictionary

To determine the number of key-value pairs in a dictionary, you can use the len() function. Here’s an example:

student = {"name": "Alice", "age": 25, "grade": "A"}

length = len(student)

print(length)  # Output: 3

Here, we calculate the length of the student dictionary using the len() function. The function returns the number of key-value pairs in the dictionary.

Dictionary Comprehensions

Dictionary comprehensions are a concise and efficient way to create dictionaries in Python. They follow a similar concept to list comprehensions but allow you to create dictionaries with key-value pairs in a single line of code. Dictionary comprehensions provide a clean and readable syntax for generating dictionaries based on specific conditions or transformations.

Creating Dictionaries Using Comprehensions

To create a dictionary using a comprehension, you need to define the key-value pairs within curly braces ({}) and specify the key-value expression. 

squares = {x: x**2 for x in range(1, 6)}

Here, we create a dictionary called squares using a comprehension. The expression x: x**2 represents the key-value pairs, where the key is x and the value is x**2. We iterate over a range from 1 to 6 and generate key-value pairs where the keys are the numbers and the values are their squares. The resulting dictionary will look like this: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}.

Advantages and Use Cases of Dictionary Comprehensions:

Dictionary comprehensions offer several advantages and can be used in various scenarios, such as:

  • Concise and Readable Code: Dictionary comprehensions let you express complex logic or transformations in a single line of code, improving code readability and making your intentions clear.
  • Filtering and Transformation: It can be used to filter or modify data. This enables you to create dictionaries based on specific requirements.
  • Efficient Data Generation: You can generate dictionaries efficiently, reducing the amount of code and improving performance.
  • Data Restructuring: Dictionary comprehensions are handy when you need to restructure data from one format to another. You can map existing keys to new values or even swap keys and values within the comprehension.

Nested Dictionaries

A nested dictionary is a dictionary that contains another dictionary (or dictionaries) as its values. This allows for a hierarchical structure, where you can organize and store related data within the nested levels. In other words, the values of a dictionary can be dictionaries themselves.

Accessing and Modifying Values in Nested Dictionaries

To access values in a nested dictionary, you can use multiple square brackets to specify the keys at each level. Here’s an example:

students = {

    "Alice": {

        "age": 25,

        "grade": "A"

    },

    "Bob": {

        "age": 30,

        "grade": "B"

    }

}

print(students["Alice"]["age"])  # Output: 25

Here, we have a dictionary called students, where each key represents a student’s name, and the corresponding value is a nested dictionary containing the student’s age and grade. By using multiple square brackets, we can access specific values within the nested levels.

To modify values in a nested dictionary, you can follow a similar approach. For example:

students["Alice"]["grade"] = "A+"

Here, we update the value of the “grade” key for the student named “Alice” to “A+”. This modification applies directly to the nested dictionary within the main dictionary.

Examples of Nested Dictionary

Nested dictionaries can be useful in various scenarios. Here are a few examples:

  • Managing Student Records: You can use a nested dictionary structure to store student information, such as names, ages, and grades. Each student’s details can be represented by a nested dictionary within the main dictionary.
  • Organizing Inventory Data: If you’re working on an inventory management system, nested dictionaries can be handy for organizing product details. Each product can have its own dictionary containing attributes like name, price, quantity, etc.
  • Storing Multi-Level Configuration Settings: When dealing with configuration settings, you may have multiple levels of settings, such as sections and subsections. A nested dictionary can represent this hierarchical structure, allowing you to access and modify settings at different levels easily.

Dictionary Manipulation Techniques

Let’s explore some handy techniques for manipulating dictionaries in Python.

Sorting Dictionaries by Keys or Values

Python provides convenient methods to sort dictionaries based on either their keys or values. Here are a couple of examples:

To sort a dictionary by its keys, you can use the sorted() function along with the keys() method. Here’s an example:

student_grades = {"Alice": 85, "Bob": 92, "Charlie": 78}

sorted_by_keys = {key: student_grades[key] for key in sorted(student_grades.keys())}

Here, we create a new dictionary called sorted_by_keys by iterating over the keys of the student_grades dictionary in sorted order. This will result in a dictionary with the keys sorted alphabetically: {“Alice”: 85, “Bob”: 92, “Charlie”: 78}.

To sort a dictionary by its values, you can use the sorted() function with a lambda function as the key parameter. Here’s an example:

student_grades = {"Alice": 85, "Bob": 92, "Charlie": 78}

sorted_by_values = {key: value for key, value in sorted(student_grades.items(), key=lambda item: item[1])}

Here, we create a new dictionary called sorted_by_values by sorting the items of the student_grades dictionary based on their values using a lambda function. The resulting dictionary will be sorted in ascending order by values: {“Charlie”: 78, “Alice”: 85, “Bob”: 92}.

Filtering Dictionaries Based on Certain Criteria

You can filter dictionaries based on specific criteria using conditional statements and dictionary comprehensions. Here’s an example:

student_grades = {"Alice": 85, "Bob": 92, "Charlie": 78}

filtered_grades = {key: value for key, value in student_grades.items() if value >= 80}

Here, we create a new dictionary called filtered_grades by iterating over the items of the student_grades dictionary and including only those with values greater than or equal to 80. The resulting dictionary will contain only the key-value pairs that satisfy the given condition: {“Alice”: 85, “Bob”: 92}.

Creating a Dictionary from Two Lists using zip()

You can create a dictionary by combining two lists using the zip() function. Here’s an example:

names = ["Alice", "Bob", "Charlie"]

ages = [25, 30, 28]

combined_dict = {name: age for name, age in zip(names, ages)}

Here, we use zip() to combine the names and ages lists, and then create a new dictionary called combined_dict. Each name from the names list becomes key, and each corresponding age from the ages list becomes the respective value in the dictionary: {“Alice”: 25, “Bob”: 30, “Charlie”: 28}.

Dictionary Methods and Built-in Functions

Whether you need to access keys, values, or items, retrieve specific values, remove entries, or perform general operations like finding the length or maximum/minimum values, these methods and functions have got you covered.

Commonly Used Dictionary Methods

  • keys(): It returns a view object that contains all the keys of a dictionary. This allows you to access and iterate over the keys conveniently.
  • values(): It returns a view object that contains all the values of a dictionary. It provides a way to access and iterate over the values stored in the dictionary.
  • items(): It returns a view object that contains all the key-value pairs of a dictionary as tuples. It allows you to access and iterate over the key-value pairs together.
  • get(key, default): It retrieves the value associated with a specific key in the dictionary. If the key is not found, it returns a default value instead of raising an error.
  • pop(key, default): It removes and returns the value associated with a specific key from the dictionary. If the key is not found, it returns a default value or raises a KeyError if no default value is provided.

Built-in Functions for Dictionaries

  • len(): It returns the number of key-value pairs in a dictionary. It’s a convenient way to determine the size or length of a dictionary.
  • max(): It can be used to find the maximum key or value in a dictionary, based on their natural ordering. It’s useful when you need to find the largest key or value in a dictionary.
  • min(): It works similarly to max(), but it finds the minimum key or value in a dictionary based on their natural ordering.

Advanced Dictionary Techniques

By understanding these advanced techniques, you can expand your dictionary skills and use dictionaries more effectively in Python. 

Handling Dictionary Collisions and Hash Functions

In Python, dictionaries use hash functions to map keys to specific locations within the underlying data structure. Occasionally, two keys may produce the same hash value, resulting in a collision. Python handles these collisions automatically, but it’s helpful to understand the concepts.

Hash functions are responsible for generating hash codes, unique identifiers associated with each key. Python’s built-in hash function produces these hash codes. When a collision occurs, Python uses a technique called open addressing or chaining to resolve it.

As a user, you don’t need to worry too much about handling collisions or hash functions directly. Python’s dictionary implementation takes care of this complexity behind the scenes, ensuring efficient key-value lookups and updates.

Working with Dictionaries as Function Arguments and Return Values

Dictionaries are versatile data structures that can be passed as arguments to functions and returned as function results. This allows for flexible and dynamic interactions. 

  • Passing Dictionaries as Function Arguments:

It enables you to provide key-value pairs as inputs. This is particularly useful when you have a varying number of arguments or want to bundle related data together. Functions can then access and utilize the dictionary’s contents as needed.

  • Returning Dictionaries from Functions:

Functions can also return dictionaries as their results. This allows you to encapsulate and provide computed or processed data in a structured manner. The calling code can then access and utilize the returned dictionary to retrieve the desired information.

Working with dictionaries in function arguments and return values promotes flexibility and modularity in your code. It allows for easy communication of data between different parts of your program.

Customizing Dictionaries using OrderedDict and defaultdict

Python provides additional dictionary variants that offer customization beyond the standard dictionary implementation. Let’s explore two such variants:

The OrderedDict class maintains the order in which key-value pairs are inserted. Standard dictionaries do not guarantee any specific order. By using OrderedDict, you can iterate over the key-value pairs in the order they were added. This can be helpful when order matters, such as preserving the order of elements in a configuration or processing steps.

The defaultdict class, available in the collections module, provides a default value for keys that do not exist in the dictionary. This eliminates the need for manual checks to handle missing keys. You can specify the default value when creating a defaultdict. This is particularly useful when working with counters, frequency distributions, or grouping data.

Real-world Examples and Applications

Let’s explore some real-world examples and applications of dictionaries in Python. 

Data Manipulation

Dictionaries are excellent for organizing and manipulating data. For instance, imagine you have a dataset of students with their names, grades, and subjects. You can use dictionaries to represent each student, where the name is the key and the associated values contain their grade and subjects. This allows you to easily access and update individual student records.

Configuration Settings

Dictionaries are commonly used to store and manage configuration settings in applications. For instance, you can create a dictionary to hold various settings, such as the database connection details, file paths, and user preferences. By using key-value pairs, you can easily access and modify these settings throughout your program.

Dictionaries can also be powerful tools for solving programming problems. Here are a few examples:

Counting and Frequency Analysis

Dictionaries are often employed for counting occurrences and performing frequency analysis. For instance, you can use a dictionary to count the frequency of words in a text document or track the occurrence of characters in a string, which can be helpful for various text processing tasks.

Grouping and Categorization

Dictionaries are useful for grouping and categorizing data based on specific criteria. For instance, you can use dictionaries to group students by their grades, employees by departments, or products by categories. This allows for efficient data organization and retrieval.

Memoization

Memoization is a technique used to optimize function calls by storing the results of expensive computations. Dictionaries are often employed as a cache to store previously computed values. By using the input arguments as keys and the computed results as values, you can avoid redundant computations and improve the performance of your code.

Concluding Thoughts

We’ve covered various aspects of dictionaries in Python, exploring key concepts and demonstrating their practical applications. We’ve seen how to create and access dictionaries, modify and update their contents, perform common operations and methods, utilize advanced techniques, and apply dictionaries to real-world scenarios and programming problems.

By now, you should have a solid understanding of how dictionaries work and their benefits. However, there’s always more to learn and discover! Dictionaries offer a vast array of possibilities, and we encourage you to continue exploring and experimenting with them. Try different techniques, combine dictionaries with other data structures, and apply them to solve diverse challenges.