Python
Python - Dictionary Comprehension
Dictionary comprehension is a powerful and elegant way to create dictionaries in Python. Let's explore this concise syntax that can replace multiple lines of traditional dictionary creation code.
Basic Dictionary Comprehension
The simplest form follows this pattern:
✳️ Syntax:
{key: value for item in iterable}
📌 Example:
Here's how to create the same dictionary using a traditional for loop instead of dictionary comprehension:
Both versions create the same dictionary:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
👣 Explanation:
The process in the traditional loop is more explicit:
- First, we create an empty dictionary
- Then we iterate through numbers 0 to 4
- For each number, we create a new key-value pair where:
- The key is the number (x)
- The value is the square of that number (x**2)
While the dictionary comprehension is more concise, both methods produce exactly the same result. The choice between them often comes down to readability and personal/team preference.
Adding Conditions
✳️ Syntax:
{key: value for item in iterable if condition}
📌 Example:
In this code snippet, we are creating a dictionary of only even numbers and their squares.
👣 Explanation:
- This
range(8)
function generates a sequence of numbers from 0 to 7 (since the stop value is exclusive): [0, 1, 2, 3, 4, 5, 6, 7]. - The comprehension iterates over each number
x
in the range of 0 to 7. - The condition
x % 2 == 0
filters out only the even numbers. The modulo operator%
returns the remainder of dividing x by 2. If the remainder is 0, then x is even. The comprehension filters this to only even numbers: [0, 2, 4, 6] - For each even number
x
, the dictionary storesx
as the key andx**2
(square ofx
) as the value.
More Complex Expressions
You can use more complex expressions for both keys and values.
📌 Example 1: Create a dictionary with string manipulation. In this code snippet, we are creating a dictionary that maps each character in the word "PYTHON" to its position (index) in the word using a dictionary comprehension.
👣 Explanation:
- We start with the string word containing "PYTHON".
- The
enumerate
function returns an iterator of tuples, where each tuple contains an index and the corresponding character from the string. For the string "PYTHON",enumerate(word)
will produce:
[(0, 'P'), (1, 'Y'), (2, 'T'), (3, 'H'), (4, 'O'), (5, 'N')]
- The comprehension iterates over each tuple
(index, char)
produced byenumerate(word)
. - For each tuple
(index, char)
, the dictionary storeschar
(the character) as the key andindex
(its position in the string) as the value.
📌 Example 2: Mathematical expressions. We are creating a dictionary that maps each number in a given range to the sine
of that number using the math.sin
function and a dictionary comprehension.
👣 Explanation:
- We start by importing the
math
module, which gives us access to mathematical functions, includingmath.sin
. - The
range(3)
function generates a sequence of numbers from 0 to 2 (since the stop value is exclusive): [0, 1, 2]. - The comprehension iterates over each number
x
in the range of 0 to 2. - For each number
x
, the dictionary storesx
as the key andmath.sin(x)
(the sine ofx
) as the value. - The
print
statement then outputs the dictionary to the console.
Practical Examples
📌 Example 1. Creating a character frequency dictionary. In this code snippet, we are creating a dictionary that maps each character in a given string to the number of times it appears in that string using a dictionary comprehension.
👣 Explanation:
- We start with the string text containing "hello".
- The comprehension iterates over each character in the string text.
- For each character char, the dictionary stores
char
as the key andtext.count(char)
(the number of timeschar
appears in text) as the value.
📌 Example 2. Converting temperature from Celsius to Fahrenheit:
👣 Explanation:
- We start with a set celsius containing the temperatures: 0, 10, 20, 30, and 40 degrees Celsius.
- The comprehension iterates over each temperature
c
in the set celsius. - For each temperature
c
, the dictionary storesc
as the key and(c * 9/5) + 32
(the equivalent temperature in Fahrenheit) as the value. This formula converts a temperature from Celsius to Fahrenheit.
📌 Example 3. Creating a dictionary from two lists. In this code snippet, we are creating a dictionary that maps
country names to their capitals using a dictionary comprehension and the zip
function.
👣 Explanation:
- We start with two lists: countries containing the names of countries and capitals containing the corresponding capitals.
- The
zip
function pairs each element from the countries list with the corresponding element from the capitals list. For the given lists, it produces:
[('Greece', 'Athens'), ('Spain', 'Madrid'), ('Italy', 'Rome')]
- The comprehension iterates over each tuple
(country, capital)
provided by thezip
function. - For each tuple
(country, capital)
, the dictionary storescountry
as the key andcapital
as the value.
But this can be written significantly shorter with dict()
constructor:
👣 Explanation:
- The
dict
constructor takes the iterable of tuples produced byzip
and converts it into a dictionary. Each tuple(country, capital)
becomes a key-value pair in the dictionary.
This method combines the zip
function and dict
constructor to create the dictionary in a single line.
Both methods have similar performance.
- Use
dict(zip(...))
when you need a quick, straightforward dictionary creation from two lists. - Use dictionary comprehension when you want to include additional conditions or transformations.
Nested dictionary comprehension
You can generate nested dictionaries:
👣 Explanation:
- This comprehension has two parts:
- Outer comprehension:
for x in range(1, 3)
→ generates keys 1, 2 - Inner comprehension:
for y in range(1, 4)
→ generates values 1, 2, 3
- Outer comprehension:
Written as traditional nested loops, it would look like this:
The dictionary comprehension is more concise and often more readable once you're familiar with the syntax.
It creates the same nested structure in a single line of code, where each outer key x
maps to another dictionary containing the products of x
with each y
value.
Performance Considerations
Dictionary comprehension is not just elegant - it's also efficient:
- It's generally faster than creating a dictionary using a for loop
- It creates the dictionary in a single pass
- It's memory efficient as it doesn't create an intermediate list
In the following code we are creating a dictionary of squares for a large number of elements (times
= 1,500,000).
We compare two methods to create the dictionary: a traditional loop and a dictionary comprehension.
We measure and compare the time taken by each method to highlight the performance differences.
👣 Explanation:
- The
time
module provides functions to measure the execution time of code. - Then we set the number of iterations:
times = 1500000
to specify how many elements we want in our dictionary. - Traditional Loop Method
- The
time.perf_counter()
function gives the current value of a high-resolution performance counter, which we store instart_time
. - Then we initialize an empty dictionary
squares_loop
. - We iterate over the range of times (from 0 to 1,499,999).
- For each
x
, we add an entry tosquares_loop
where the key isx
and the value isx**2
. - We get the ending time with
end_time = time.perf_counter()
. - We calculate the total time taken by the loop method as
loop_time = end_time - start_time
- The
- Dictionary Comprehension Method
- We reset the start time value before starting the dictionary comprehension measurement.
- Using a dictionary comprehension, we create
squares_comp
in a single line. It efficiently iterates over the range of times and computes the squares. - We get the ending time
- We calculate the total time taken by the dictionary comprehension method
- We print the time taken by both methods
- We also print a comparative statement showing how many times faster the dictionary comprehension is compared to the traditional loop.
Dictionary comprehensions take advantage of internal optimizations, resulting in faster execution times.
Note that actual times will vary depending on:
- Your computer's specifications
- Python version
- System load
- Size of the dictionary being created
However, remember that readability should usually be your first priority - choose the method that makes your code clearer and easier to maintain!
Comparative Table for Comprehensions and Loops
Aspect | Comprehensions | Equivalent Loops |
---|---|---|
Simplicity and Readability | Compact and often more readable for simple transformations | More verbose, but sometimes clearer for complex logic |
Performance | Generally faster due to internal optimizations | Slightly slower due to additional overhead of loop constructs |
Expressiveness | Highly expressive, allows concise representation of simple filtering and mapping operations | More flexible for scenarios that require complex logic, multiple statements, or intermediate steps |
Use Cases | Ideal for simple transformations, filtering, and mapping where readability and conciseness are prioritized | Preferable when handling complex logic, multiple operations, or when readability of the loop structure is crucial |
Side Effects | Not ideal for operations with side effects, such as printing or modifying external variables | Suitable for operations with side effects, as multiple statements can be executed within the loop |
Nested Loops | Supports nested comprehensions but can become complex and hard to read | Easier to manage and understand nested loops due to explicit structure |
Example. Check if two Strings are Anagrams of each other
An anagram is a word or phrase formed by rearranging the letters of another word. Write a program that determines whether two words are anagrams or not. For example, night and thing.
👣 Explanation:
- Define the words
- Count letter frequencies in each word
- We create two dictionaries (
c
andd
) to store letter counts. - The dictionary comprehension counts how many times each letter appears in
word1
andword2
- We create two dictionaries (
- After execution:
c = {'n': 1, 'i': 1, 'g': 1, 'h': 1, 't': 1}
d = {'t': 1, 'h': 1, 'i': 1, 'n': 1, 'g': 1}
- Both dictionaries store the same letter counts, meaning the words have the same letters in the same frequency.
- Compare the dictionaries. If both dictionaries are equal, it means the words are anagrams, so we print "Yes". Otherwise, we print "No".
A more efficient way to count letter frequencies is by using Counter
from the collections module:
Counter(word1)
automatically creates a dictionary of letter frequencies.
The comparison remains the same but is now more efficient and readable.
FAQs on Dictionary Comprehension
What is a dictionary comprehension in Python?
A dictionary comprehension is a concise way to create dictionaries in Python
by specifying key-value pairs inside curly braces {} using a single line of code.
It follows the pattern {key: value for item in iterable}
and is often used as a shorthand for
creating dictionaries more efficiently.
How is dictionary comprehension different from list comprehension?
While list comprehension uses square brackets [] and creates a list, dictionary comprehension uses curly braces {} and requires both a key and value expression separated by a colon. Dictionary comprehension creates key-value pairs instead of single values.
What are some use cases for dictionary comprehensions?
- Filtering key-value pairs based on conditions
- Inverting a dictionary so that values become keys and vice versa
- Creating dictionaries from other iterables (e.g., lists or tuples)
- Transforming one dictionary into another (e.g., modifying keys or values)
How do I swap keys and values in a dictionary using comprehension?
You can invert a dictionary like this: