Pythonic Patterns
Dictionary Comprehension
Concise Dict Creation
You need to create a lookup table mapping names to ages. A loop and dict build-up
works, but {name: age for name, age in pairs} does it in one line. Dict
comprehensions are the idiomatic way to build dictionaries from iterables.
Basic key-value creation
Create a dictionary from a sequence.
# Basic Dictionary Comprehension
print("=== Basic Dictionary Comprehension ===\n")
# Traditional loop approach
squares_loop = {}
for x in range(1, 6):
squares_loop[x] = x ** 2
print(f"Loop: {squares_loop}")
# Dictionary comprehension
squares_comp = {x: x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")
print("\n=== Key: Value Structure ===")
# Number to its word
num_words = {1: "one", 2: "two", 3: "three"}
print(f"Manual: {num_words}")
# Same pattern with comprehension
words = ["zero", "one", "two", "three", "four"]
num_to_word = {i: words[i] for i in range(len(words))}
print(f"Comprehension: {num_to_word}")
print("\n=== From Strings ===")
# Character positions
word = "hello"
char_positions = {char: i for i, char in enumerate(word)}
print(f"'{word}' char positions: {char_positions}")
# Note: duplicate chars get last position
word2 = "banana"
char_pos2 = {char: i for i, char in enumerate(word2)}
print(f"'{word2}' char positions: {char_pos2}")
print("\n=== From Other Collections ===")
# Set to length mapping
names = {"Alice", "Bob", "Charlie"}
name_lengths = {name: len(name) for name in names}
print(f"Names: {names}")
print(f"Lengths: {name_lengths}")
print("\n=== Syntax Summary ===")
print("{key_expr: value_expr for item in iterable}")
print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")
print(" key value var source")
# Basic Dictionary Comprehension
print("=== Basic Dictionary Comprehension ===\n")
# Traditional loop approach
squares_loop = {}
for x in range(1, 6):
squares_loop[x] = x ** 2
print(f"Loop: {squares_loop}")
# Dictionary comprehension
squares_comp = {x: x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")
print("\n=== Key: Value Structure ===")
# Number to its word
num_words = {1: "one", 2: "two", 3: "three"}
print(f"Manual: {num_words}")
# Same pattern with comprehension
words = ["zero", "one", "two", "three", "four"]
num_to_word = {i: words[i] for i in range(len(words))}
print(f"Comprehension: {num_to_word}")
print("\n=== From Strings ===")
# Character positions
word = "hello"
char_positions = {char: i for i, char in enumerate(word)}
print(f"'{word}' char positions: {char_positions}")
# Note: duplicate chars get last position
word2 = "abracadabra"
char_pos2 = {char: i for i, char in enumerate(word2)}
print(f"'{word2}' char positions: {char_pos2}")
print("\n=== From Other Collections ===")
# Set to length mapping
names = {"Alice", "Bob", "Charlie"}
name_lengths = {name: len(name) for name in names}
print(f"Names: {names}")
print(f"Lengths: {name_lengths}")
print("\n=== Syntax Summary ===")
print("{key_expr: value_expr for item in iterable}")
print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")
print(" key value var source")
# Basic Dictionary Comprehension
print("=== Basic Dictionary Comprehension ===\n")
# Traditional loop approach
squares_loop = {}
for x in range(1, 6):
squares_loop[x] = x ** 2
print(f"Loop: {squares_loop}")
# Dictionary comprehension
squares_comp = {x: x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")
print("\n=== Key: Value Structure ===")
# Number to its word
num_words = {1: "one", 2: "two", 3: "three"}
print(f"Manual: {num_words}")
# Same pattern with comprehension
words = ["zero", "one", "two", "three", "four"]
num_to_word = {i: words[i] for i in range(len(words))}
print(f"Comprehension: {num_to_word}")
print("\n=== From Strings ===")
# Character positions
word = "hello"
char_positions = {char: i for i, char in enumerate(word)}
print(f"'{word}' char positions: {char_positions}")
# Note: duplicate chars get last position
word2 = "committee"
char_pos2 = {char: i for i, char in enumerate(word2)}
print(f"'{word2}' char positions: {char_pos2}")
print("\n=== From Other Collections ===")
# Set to length mapping
names = {"Alice", "Bob", "Charlie"}
name_lengths = {name: len(name) for name in names}
print(f"Names: {names}")
print(f"Lengths: {name_lengths}")
print("\n=== Syntax Summary ===")
print("{key_expr: value_expr for item in iterable}")
print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")
print(" key value var source")
squares_loop ← {}
3print("=== Basic Dictionary Comprehension ===\n")45# Traditional loop approach #?traditional6squares_loop→ {} = {}7for x in range(1, 6):output=== Basic Dictionary Comprehension ===squares_loop[x] ← 1
pass 1 of 56squares_loop = {}7for x1 in range(1, 6):8 squares_loop[x]→ 1 = x1 ** 29print(f"Loop: {squares_loop}")All 5 passes — pass 1 is the card above pass xsquares_loop[x]1 1 1 2 2 4 3 3 9 4 4 16 5 5 25 squares_comp ← {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}, num_words ← {1: 'one', 2: 'two', 3: 'three'}
8 squares_loop[x] = x ** 29print(f"Loop: {squares_loop{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1011# Dictionary comprehension #?comprehension12squares_comp→ {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} = {x: x ** 2 for x in range(1, 6)} #?dictcomp13print(f"Comprehension: {squares_comp{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1415print("\n=== Key: Value Structure ===")1617# Number to its word #?numword18num_words→ {1: 'one', 2: 'two', 3: 'three'} = {1: "one", 2: "two", 3: "three"}19print(f"Manual: {num_words{1: 'one', 2: 'two', 3: 'three'}}")2021# Same pattern with comprehension22words→ ['zero', 'one', 'two', 'three', 'four'] = ["zero", "one", "two", "three", "four"]23num_to_word→ {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} = {i: words[i](empty) for i in range(len(words['zero', 'one', 'two', 'three', 'four']))} #?indexword24print(f"Comprehension: {num_to_word{0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'}}")2526print("\n=== From Strings ===")2728# Character positions #?charpos29word→ hello = "hello"30char_positions→ {'h': 0, 'e': 1, 'l': 3, 'o': 4} = {char(empty): i(empty) for i, char in enumerate(wordhello)} #?enumerate31print(f"'{wordhello}' char positions: {char_positions{'h': 0, 'e': 1, 'l': 3, 'o': 4}}")3233# Note: duplicate chars get last position34word2→ banana = "banana" #@word2="abracadabra", "committee"35char_pos2→ {'b': 0, 'a': 5, 'n': 4} = {char(empty): i(empty) for i, char in enumerate(word2banana)}36print(f"'{word2banana}' char positions: {char_pos2{'b': 0, 'a': 5, 'n': 4}}")3738print("\n=== From Other Collections ===")3940# Set to length mapping #?setmap41names→ {'Charlie', 'Alice', 'Bob'} = {"Alice", "Bob", "Charlie"}42name_lengths→ {'Charlie': 7, 'Alice': 5, 'Bob': 3} = {name: len(name) for name in names{'Charlie', 'Alice', 'Bob'}} #?namelen43print(f"Names: {names{'Charlie', 'Alice', 'Bob'}}")44print(f"Lengths: {name_lengths{'Charlie': 7, 'Alice': 5, 'Bob': 3}}")4546print("\n=== Syntax Summary ===")47print("{key_expr: value_expr for item in iterable}")48print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")49print(" key value var source")50#@help traditionaloutputLoop: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} Comprehension: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} === Key: Value Structure === Manual: {1: 'one', 2: 'two', 3: 'three'} Comprehension: {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} === From Strings === 'hello' char positions: {'h': 0, 'e': 1, 'l': 3, 'o': 4} 'banana' char positions: {'b': 0, 'a': 5, 'n': 4} === From Other Collections === Names: {'Charlie', 'Alice', 'Bob'} Lengths: {'Charlie': 7, 'Alice': 5, 'Bob': 3} === Syntax Summary === {key_expr: value_expr for item in iterable} ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^ key value var source
squares_loop ← {}
3print("=== Basic Dictionary Comprehension ===\n")45# Traditional loop approach6squares_loop→ {} = {}7for x in range(1, 6):output=== Basic Dictionary Comprehension ===squares_loop[x] ← 1
pass 1 of 56squares_loop = {}7for x1 in range(1, 6):8 squares_loop[x]→ 1 = x1 ** 29print(f"Loop: {squares_loop}")All 5 passes — pass 1 is the card above pass xsquares_loop[x]1 1 1 2 2 4 3 3 9 4 4 16 5 5 25 squares_comp ← {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}, num_words ← {1: 'one', 2: 'two', 3: 'three'}
8 squares_loop[x] = x ** 29print(f"Loop: {squares_loop{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1011# Dictionary comprehension12squares_comp→ {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} = {x: x ** 2 for x in range(1, 6)}13print(f"Comprehension: {squares_comp{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1415print("\n=== Key: Value Structure ===")1617# Number to its word18num_words→ {1: 'one', 2: 'two', 3: 'three'} = {1: "one", 2: "two", 3: "three"}19print(f"Manual: {num_words{1: 'one', 2: 'two', 3: 'three'}}")2021# Same pattern with comprehension22words→ ['zero', 'one', 'two', 'three', 'four'] = ["zero", "one", "two", "three", "four"]23num_to_word→ {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} = {i: words[i](empty) for i in range(len(words['zero', 'one', 'two', 'three', 'four']))}24print(f"Comprehension: {num_to_word{0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'}}")2526print("\n=== From Strings ===")2728# Character positions29word→ hello = "hello"30char_positions→ {'h': 0, 'e': 1, 'l': 3, 'o': 4} = {char(empty): i(empty) for i, char in enumerate(wordhello)}31print(f"'{wordhello}' char positions: {char_positions{'h': 0, 'e': 1, 'l': 3, 'o': 4}}")3233# Note: duplicate chars get last position34word2→ abracadabra = "abracadabra"35char_pos2→ {'a': 10, 'b': 8, 'r': 9, 'c': 4, 'd': 6} = {char(empty): i(empty) for i, char in enumerate(word2abracadabra)}36print(f"'{word2abracadabra}' char positions: {char_pos2{'a': 10, 'b': 8, 'r': 9, 'c': 4, 'd': 6}}")3738print("\n=== From Other Collections ===")3940# Set to length mapping41names→ {'Alice', 'Bob', 'Charlie'} = {"Alice", "Bob", "Charlie"}42name_lengths→ {'Alice': 5, 'Bob': 3, 'Charlie': 7} = {name: len(name) for name in names{'Alice', 'Bob', 'Charlie'}}43print(f"Names: {names{'Alice', 'Bob', 'Charlie'}}")44print(f"Lengths: {name_lengths{'Alice': 5, 'Bob': 3, 'Charlie': 7}}")4546print("\n=== Syntax Summary ===")47print("{key_expr: value_expr for item in iterable}")48print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")49print(" key value var source")outputLoop: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} Comprehension: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} === Key: Value Structure === Manual: {1: 'one', 2: 'two', 3: 'three'} Comprehension: {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} === From Strings === 'hello' char positions: {'h': 0, 'e': 1, 'l': 3, 'o': 4} 'abracadabra' char positions: {'a': 10, 'b': 8, 'r': 9, 'c': 4, 'd': 6} === From Other Collections === Names: {'Alice', 'Bob', 'Charlie'} Lengths: {'Alice': 5, 'Bob': 3, 'Charlie': 7} === Syntax Summary === {key_expr: value_expr for item in iterable} ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^ key value var source
squares_loop ← {}
3print("=== Basic Dictionary Comprehension ===\n")45# Traditional loop approach6squares_loop→ {} = {}7for x in range(1, 6):output=== Basic Dictionary Comprehension ===squares_loop[x] ← 1
pass 1 of 56squares_loop = {}7for x1 in range(1, 6):8 squares_loop[x]→ 1 = x1 ** 29print(f"Loop: {squares_loop}")All 5 passes — pass 1 is the card above pass xsquares_loop[x]1 1 1 2 2 4 3 3 9 4 4 16 5 5 25 squares_comp ← {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}, num_words ← {1: 'one', 2: 'two', 3: 'three'}
8 squares_loop[x] = x ** 29print(f"Loop: {squares_loop{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1011# Dictionary comprehension12squares_comp→ {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} = {x: x ** 2 for x in range(1, 6)}13print(f"Comprehension: {squares_comp{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}}")1415print("\n=== Key: Value Structure ===")1617# Number to its word18num_words→ {1: 'one', 2: 'two', 3: 'three'} = {1: "one", 2: "two", 3: "three"}19print(f"Manual: {num_words{1: 'one', 2: 'two', 3: 'three'}}")2021# Same pattern with comprehension22words→ ['zero', 'one', 'two', 'three', 'four'] = ["zero", "one", "two", "three", "four"]23num_to_word→ {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} = {i: words[i](empty) for i in range(len(words['zero', 'one', 'two', 'three', 'four']))}24print(f"Comprehension: {num_to_word{0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'}}")2526print("\n=== From Strings ===")2728# Character positions29word→ hello = "hello"30char_positions→ {'h': 0, 'e': 1, 'l': 3, 'o': 4} = {char(empty): i(empty) for i, char in enumerate(wordhello)}31print(f"'{wordhello}' char positions: {char_positions{'h': 0, 'e': 1, 'l': 3, 'o': 4}}")3233# Note: duplicate chars get last position34word2→ committee = "committee"35char_pos2→ {'c': 0, 'o': 1, 'm': 3, 'i': 4, 't': 6, 'e': 8} = {char(empty): i(empty) for i, char in enumerate(word2committee)}36print(f"'{word2committee}' char positions: {char_pos2{'c': 0, 'o': 1, 'm': 3, 'i': 4, 't': 6, 'e': 8}}")3738print("\n=== From Other Collections ===")3940# Set to length mapping41names→ {'Alice', 'Charlie', 'Bob'} = {"Alice", "Bob", "Charlie"}42name_lengths→ {'Alice': 5, 'Charlie': 7, 'Bob': 3} = {name: len(name) for name in names{'Alice', 'Charlie', 'Bob'}}43print(f"Names: {names{'Alice', 'Charlie', 'Bob'}}")44print(f"Lengths: {name_lengths{'Alice': 5, 'Charlie': 7, 'Bob': 3}}")4546print("\n=== Syntax Summary ===")47print("{key_expr: value_expr for item in iterable}")48print(" ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^")49print(" key value var source")outputLoop: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} Comprehension: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} === Key: Value Structure === Manual: {1: 'one', 2: 'two', 3: 'three'} Comprehension: {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four'} === From Strings === 'hello' char positions: {'h': 0, 'e': 1, 'l': 3, 'o': 4} 'committee' char positions: {'c': 0, 'o': 1, 'm': 3, 'i': 4, 't': 6, 'e': 8} === From Other Collections === Names: {'Alice', 'Charlie', 'Bob'} Lengths: {'Alice': 5, 'Charlie': 7, 'Bob': 3} === Syntax Summary === {key_expr: value_expr for item in iterable} ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^ key value var source
{key: value for item in iterable} - define both key and value.
From parallel lists
Combine two lists into a dictionary.
# Dictionary from Parallel Lists
print("=== Creating Dict from Two Lists ===\n")
# Two parallel lists
keys = ["name", "age", "city"]
values = ["Alice", 30, "NYC"]
print(f"Keys: {keys}")
print(f"Values: {values}")
# Using zip() with dict comprehension
person = {k: v for k, v in zip(keys, values)}
print(f"Dict: {person}")
# Shortcut: dict() constructor
person2 = dict(zip(keys, values))
print(f"dict(zip()): {person2}")
print("\n=== Multiple Records ===")
# Employee data as parallel lists
ids = [101, 102, 103]
names = ["Alice", "Bob", "Charlie"]
salaries = [50000, 60000, 55000]
# ID to name mapping
id_to_name = {i: n for i, n in zip(ids, names)}
print(f"ID → Name: {id_to_name}")
# ID to (name, salary) tuple
id_to_info = {i: (n, s) for i, n, s in zip(ids, names, salaries)}
print(f"ID → Info: {id_to_info}")
print("\n=== Index-Based Keys ===")
fruits = ["apple", "banana", "cherry"]
# Index as key
indexed = {i: fruit for i, fruit in enumerate(fruits)}
print(f"Indexed: {indexed}")
# Starting from 1
indexed_from_1 = {i: fruit for i, fruit in enumerate(fruits, start=1)}
print(f"From 1: {indexed_from_1}")
print("\n=== Unequal Lengths ===")
short = [1, 2]
long = ['a', 'b', 'c', 'd']
# zip stops at shorter
result = {k: v for k, v in zip(short, long)}
print(f"short={short}, long={long}")
print(f"zip result: {result}")
keys ← ['name', 'age', 'city'], values ← ['Alice', 30, 'NYC']
3print("=== Creating Dict from Two Lists ===\n")45# Two parallel lists #?parallel6keys→ ['name', 'age', 'city'] = ["name", "age", "city"]7values→ ['Alice', 30, 'NYC'] = ["Alice", 30, "NYC"]8print(f"Keys: {keys['name', 'age', 'city']}")9print(f"Values: {values['Alice', 30, 'NYC']}")1011# Using zip() with dict comprehension #?zipdict12person→ {'name': 'Alice', 'age': 30, 'city': 'NYC'} = {k(empty): v(empty) for k, v in zip(keys['name', 'age', 'city'], values['Alice', 30, 'NYC'])} #?zipcomp13print(f"Dict: {person{'name': 'Alice', 'age': 30, 'city': 'NYC'}}")1415# Shortcut: dict() constructor #?dictctr16person2→ {'name': 'Alice', 'age': 30, 'city': 'NYC'} = dict(zip(keys['name', 'age', 'city'], values['Alice', 30, 'NYC']))17print(f"dict(zip()): {person2{'name': 'Alice', 'age': 30, 'city': 'NYC'}}")1819print("\n=== Multiple Records ===")2021# Employee data as parallel lists #?employees22ids→ [101, 102, 103] = [101, 102, 103]23names→ ['Alice', 'Bob', 'Charlie'] = ["Alice", "Bob", "Charlie"]24salaries→ [50000, 60000, 55000] = [50000, 60000, 55000]2526# ID to name mapping #?idname27id_to_name→ {101: 'Alice', 102: 'Bob', 103: 'Charlie'} = {i(empty): n(empty) for i, n in zip(ids[101, 102, 103], names['Alice', 'Bob', 'Charlie'])}28print(f"ID → Name: {id_to_name{101: 'Alice', 102: 'Bob', 103: 'Charlie'}}")2930# ID to (name, salary) tuple #?tuple31id_to_info→ {101: ('Alice', 50000), 102: ('Bob', 60000), 103: ('Charlie', 55000)} = {i(empty): (n(empty), s(empty)) for i, n, s in zip(ids[101, 102, 103], names['Alice', 'Bob', 'Charlie'], salaries[50000, 60000, 55000])} #?zip332print(f"ID → Info: {id_to_info{101: ('Alice', 50000), 102: ('Bob', 60000), 103: ('Charlie', 55000)}}")3334print("\n=== Index-Based Keys ===")3536fruits→ ['apple', 'banana', 'cherry'] = ["apple", "banana", "cherry"] #?index3738# Index as key #?enumdict39indexed→ {0: 'apple', 1: 'banana', 2: 'cherry'} = {i(empty): fruit(empty) for i, fruit in enumerate(fruits['apple', 'banana', 'cherry'])}40print(f"Indexed: {indexed{0: 'apple', 1: 'banana', 2: 'cherry'}}")4142# Starting from 1 #?start143indexed_from_1→ {1: 'apple', 2: 'banana', 3: 'cherry'} = {i(empty): fruit(empty) for i, fruit in enumerate(fruits['apple', 'banana', 'cherry'], start=1)}44print(f"From 1: {indexed_from_1{1: 'apple', 2: 'banana', 3: 'cherry'}}")4546print("\n=== Unequal Lengths ===")4748short→ [1, 2] = [1, 2]49long→ ['a', 'b', 'c', 'd'] = ['a', 'b', 'c', 'd'] #?unequal5051# zip stops at shorter #?zipstop52result→ {1: 'a', 2: 'b'} = {k(empty): v(empty) for k, v in zip(short[1, 2], long['a', 'b', 'c', 'd'])}53print(f"short={short[1, 2]}, long={long['a', 'b', 'c', 'd']}")54print(f"zip result: {result{1: 'a', 2: 'b'}}")55#@help paralleloutput=== Creating Dict from Two Lists === Keys: ['name', 'age', 'city'] Values: ['Alice', 30, 'NYC'] Dict: {'name': 'Alice', 'age': 30, 'city': 'NYC'} dict(zip()): {'name': 'Alice', 'age': 30, 'city': 'NYC'} === Multiple Records === ID → Name: {101: 'Alice', 102: 'Bob', 103: 'Charlie'} ID → Info: {101: ('Alice', 50000), 102: ('Bob', 60000), 103: ('Charlie', 55000)} === Index-Based Keys === Indexed: {0: 'apple', 1: 'banana', 2: 'cherry'} From 1: {1: 'apple', 2: 'banana', 3: 'cherry'} === Unequal Lengths === short=[1, 2], long=['a', 'b', 'c', 'd'] zip result: {1: 'a', 2: 'b'}
Use zip() to pair up keys and values: {k: v for k, v in zip(keys, values)}.
Filter entries
Include only certain key-value pairs.
# Filtering in Dictionary Comprehension
print("=== Filtering Dictionary Items ===\n")
# Original dictionary
prices = {"apple": 1.50, "banana": 0.75, "cherry": 3.00, "date": 2.25, "elderberry": 4.50}
print(f"All prices: {prices}")
# Filter by value: expensive items (> $2)
expensive = {k: v for k, v in prices.items() if v > 2.00}
print(f"Expensive (>$2): {expensive}")
# Filter by key: names starting with vowel
vowel_fruits = {k: v for k, v in prices.items() if k[0] in 'aeiou'}
print(f"Vowel start: {vowel_fruits}")
print("\n=== Filtering from Source Dict ===")
scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "Diana": 95, "Eve": 65}
print(f"All scores: {scores}")
# Passing students (>= 70)
passing = {name: score for name, score in scores.items() if score >= 70}
print(f"Passing: {passing}")
# Top performers (>= 90)
top = {name: score for name, score in scores.items() if score >= 90}
print(f"Top (>=90): {top}")
print("\n=== Multiple Conditions ===")
products = {
"laptop": {"price": 999, "stock": 5},
"phone": {"price": 699, "stock": 0},
"tablet": {"price": 399, "stock": 10},
"watch": {"price": 299, "stock": 3},
}
# In stock AND affordable (< $500)
available_affordable = {
name: info
for name, info in products.items()
if info["stock"] > 0 and info["price"] < 500
}
print(f"Available & <$500: {available_affordable}")
print("\n=== Filtering with External Data ===")
# Keep only selected keys
all_data = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
keep = {"a", "c", "e"}
filtered = {k: v for k, v in all_data.items() if k in keep}
print(f"All: {all_data}")
print(f"Keep {keep}: {filtered}")
prices ← {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5}
3print("=== Filtering Dictionary Items ===\n")45# Original dictionary #?original6prices→ {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5} = {"apple": 1.50, "banana": 0.75, "cherry": 3.00, "date": 2.25, "elderberry": 4.50}7print(f"All prices: {prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5}}")89# Filter by value: expensive items (> $2) #?byvalue10expensive→ {'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5} = {k(empty): v(empty) for k, v in prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5}.items() if v > 2.00} #?filtervalue11print(f"Expensive (>$2): {expensive{'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5}}")1213# Filter by key: names starting with vowel #?bykey14vowel_fruits→ {'apple': 1.5, 'elderberry': 4.5} = {k(empty): v(empty) for k, v in prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5}.items() if k[0](empty) in 'aeiou'} #?filterkey15print(f"Vowel start: {vowel_fruits{'apple': 1.5, 'elderberry': 4.5}}")1617print("\n=== Filtering from Source Dict ===")1819scores→ {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95, 'Eve': 65} = {"Alice": 85, "Bob": 92, "Charlie": 78, "Diana": 95, "Eve": 65} #?scores20print(f"All scores: {scores{'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95, 'Eve': 65}}")2122# Passing students (>= 70) #?passing23passing→ {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95} = {name(empty): score(empty) for name, score in scores{'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95, 'Eve': 65}.items() if score >= 70}24print(f"Passing: {passing{'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95}}")2526# Top performers (>= 90)27top→ {'Bob': 92, 'Diana': 95} = {name(empty): score(empty) for name, score in scores{'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95, 'Eve': 65}.items() if score >= 90}28print(f"Top (>=90): {top{'Bob': 92, 'Diana': 95}}")2930print("\n=== Multiple Conditions ===")3132products→ {'laptop': {'price': 999, 'stock': 5}, 'phone': {'price': 699, 'stock': 0}, 'tablet': {'price': 399, 'stock': 10}, 'watch': {'price': 299, 'stock': 3}} = {33 "laptop": {"price": 999, "stock": 5},34 "phone": {"price": 699, "stock": 0},35 "tablet": {"price": 399, "stock": 10},36 "watch": {"price": 299, "stock": 3},37} #?products3839# In stock AND affordable (< $500) #?multiple40available_affordable→ {'tablet': {'price': 399, 'stock': 10}, 'watch': {'price': 299, 'stock': 3}} = {41 name(empty): info(empty) 42 for name(empty), info(empty) in products{'laptop': {'price': 999, 'stock': 5}, 'phone': {'price': 699, 'stock': 0}, 'tablet': {'price': 399, 'stock': 10}, 'watch': {'price': 299, 'stock': 3}}.items() 43 if info["stock"](empty) > 0 and info["price"](empty) < 50044} #?multifilter45print(f"Available & <$500: {available_affordable{'tablet': {'price': 399, 'stock': 10}, 'watch': {'price': 299, 'stock': 3}}}")4647print("\n=== Filtering with External Data ===")4849# Keep only selected keys #?selected50all_data→ {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}51keep→ {'a', 'c', 'e'} = {"a", "c", "e"}5253filtered→ {'a': 1, 'c': 3, 'e': 5} = {k(empty): v(empty) for k, v in all_data{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}.items() if k in keep{'a', 'c', 'e'}} #?keeponly54print(f"All: {all_data{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}}")55print(f"Keep {keep{'a', 'c', 'e'}}: {filtered{'a': 1, 'c': 3, 'e': 5}}")56#@help originaloutput=== Filtering Dictionary Items === All prices: {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5} Expensive (>$2): {'cherry': 3.0, 'date': 2.25, 'elderberry': 4.5} Vowel start: {'apple': 1.5, 'elderberry': 4.5} === Filtering from Source Dict === All scores: {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95, 'Eve': 65} Passing: {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95} Top (>=90): {'Bob': 92, 'Diana': 95} === Multiple Conditions === Available & <$500: {'tablet': {'price': 399, 'stock': 10}, 'watch': {'price': 299, 'stock': 3}} === Filtering with External Data === All: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} Keep {'a', 'c', 'e'}: {'a': 1, 'c': 3, 'e': 5}
Add if condition to filter: {k: v for k, v in items if v > 0}.
Transform keys and values
Modify keys, values, or both.
# Transforming Keys and Values
print("=== Transforming Values ===\n")
# Original prices
prices = {"apple": 1.50, "banana": 0.75, "cherry": 3.00}
print(f"Original: {prices}")
# Apply 10% discount
discounted = {k: round(v * 0.9, 2) for k, v in prices.items()}
print(f"10% off: {discounted}")
# Convert to cents
cents = {k: int(v * 100) for k, v in prices.items()}
print(f"In cents: {cents}")
print("\n=== Transforming Keys ===")
# Original with lowercase keys
data = {"name": "Alice", "age": 30, "city": "NYC"}
print(f"Original: {data}")
# Uppercase keys
upper_keys = {k.upper(): v for k, v in data.items()}
print(f"Upper keys: {upper_keys}")
# Add prefix to keys
prefixed = {f"user_{k}": v for k, v in data.items()}
print(f"Prefixed: {prefixed}")
print("\n=== Transform Both ===")
raw_scores = {"alice": "85", "bob": "92", "charlie": "78"}
print(f"Raw: {raw_scores}")
# Capitalize names, convert scores to int
clean_scores = {name.capitalize(): int(score) for name, score in raw_scores.items()}
print(f"Clean: {clean_scores}")
print("\n=== Conditional Transform ===")
numbers = {"a": -3, "b": 5, "c": -1, "d": 8}
print(f"Numbers: {numbers}")
# Absolute values
absolute = {k: abs(v) for k, v in numbers.items()}
print(f"Absolute: {absolute}")
# Conditional: double positives, negate negatives
transformed = {k: v * 2 if v > 0 else -v for k, v in numbers.items()}
print(f"Transformed: {transformed}")
print("\n=== Computed Keys ===")
items = ["apple", "banana", "cherry"]
# Length as key
by_length = {len(item): item for item in items}
print(f"By length: {by_length}")
# First letter as key
by_first = {item[0]: item for item in items}
print(f"By first letter: {by_first}")
# Note: duplicates overwrite!
prices ← {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0}, discounted ← {'apple': 1.35, 'banana': 0.68, 'cherry': 2.7}
3print("=== Transforming Values ===\n")45# Original prices #?original6prices→ {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0} = {"apple": 1.50, "banana": 0.75, "cherry": 3.00}7print(f"Original: {prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0}}")89# Apply 10% discount #?discount10discounted→ {'apple': 1.35, 'banana': 0.68, 'cherry': 2.7} = {k(empty): round(v(empty) * 0.9, 2) for k, v in prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0}.items()} #?transformval11print(f"10% off: {discounted{'apple': 1.35, 'banana': 0.68, 'cherry': 2.7}}")1213# Convert to cents #?cents14cents→ {'apple': 150, 'banana': 75, 'cherry': 300} = {k(empty): int(v(empty) * 100) for k, v in prices{'apple': 1.5, 'banana': 0.75, 'cherry': 3.0}.items()}15print(f"In cents: {cents{'apple': 150, 'banana': 75, 'cherry': 300}}")1617print("\n=== Transforming Keys ===")1819# Original with lowercase keys #?lowercase20data→ {'name': 'Alice', 'age': 30, 'city': 'NYC'} = {"name": "Alice", "age": 30, "city": "NYC"}21print(f"Original: {data{'name': 'Alice', 'age': 30, 'city': 'NYC'}}")2223# Uppercase keys #?upperkeys24upper_keys→ {'NAME': 'Alice', 'AGE': 30, 'CITY': 'NYC'} = {k(empty).upper(): v(empty) for k, v in data{'name': 'Alice', 'age': 30, 'city': 'NYC'}.items()} #?transformkey25print(f"Upper keys: {upper_keys{'NAME': 'Alice', 'AGE': 30, 'CITY': 'NYC'}}")2627# Add prefix to keys #?prefix28prefixed→ {'user_name': 'Alice', 'user_age': 30, 'user_city': 'NYC'} = {f"user_{k(empty)}": v(empty) for k, v in data{'name': 'Alice', 'age': 30, 'city': 'NYC'}.items()}29print(f"Prefixed: {prefixed{'user_name': 'Alice', 'user_age': 30, 'user_city': 'NYC'}}")3031print("\n=== Transform Both ===")3233raw_scores→ {'alice': '85', 'bob': '92', 'charlie': '78'} = {"alice": "85", "bob": "92", "charlie": "78"} #?rawscores34print(f"Raw: {raw_scores{'alice': '85', 'bob': '92', 'charlie': '78'}}")3536# Capitalize names, convert scores to int #?both37clean_scores→ {'Alice': 85, 'Bob': 92, 'Charlie': 78} = {name(empty).capitalize(): int(score(empty)) for name, score in raw_scores{'alice': '85', 'bob': '92', 'charlie': '78'}.items()} #?transformboth38print(f"Clean: {clean_scores{'Alice': 85, 'Bob': 92, 'Charlie': 78}}")3940print("\n=== Conditional Transform ===")4142numbers→ {'a': -3, 'b': 5, 'c': -1, 'd': 8} = {"a": -3, "b": 5, "c": -1, "d": 8} #?numbers43print(f"Numbers: {numbers{'a': -3, 'b': 5, 'c': -1, 'd': 8}}")4445# Absolute values #?absolute46absolute→ {'a': 3, 'b': 5, 'c': 1, 'd': 8} = {k(empty): abs(v(empty)) for k, v in numbers{'a': -3, 'b': 5, 'c': -1, 'd': 8}.items()}47print(f"Absolute: {absolute{'a': 3, 'b': 5, 'c': 1, 'd': 8}}")4849# Conditional: double positives, negate negatives #?conditional50transformed→ {'a': 3, 'b': 10, 'c': 1, 'd': 16} = {k(empty): v(empty) * 2 if v > 0 else -v for k, v in numbers{'a': -3, 'b': 5, 'c': -1, 'd': 8}.items()} #?condtransform51print(f"Transformed: {transformed{'a': 3, 'b': 10, 'c': 1, 'd': 16}}")5253print("\n=== Computed Keys ===")5455items→ ['apple', 'banana', 'cherry'] = ["apple", "banana", "cherry"] #?computed5657# Length as key #?lenkey58by_length→ {5: 'apple', 6: 'cherry'} = {len(item): item for item in items['apple', 'banana', 'cherry']}59print(f"By length: {by_length{5: 'apple', 6: 'cherry'}}")6061# First letter as key #?firstletter62by_first→ {'a': 'apple', 'b': 'banana', 'c': 'cherry'} = {item[0](empty): item for item in items['apple', 'banana', 'cherry']}63print(f"By first letter: {by_first{'a': 'apple', 'b': 'banana', 'c': 'cherry'}}")64# Note: duplicates overwrite!output=== Transforming Values === Original: {'apple': 1.5, 'banana': 0.75, 'cherry': 3.0} 10% off: {'apple': 1.35, 'banana': 0.68, 'cherry': 2.7} In cents: {'apple': 150, 'banana': 75, 'cherry': 300} === Transforming Keys === Original: {'name': 'Alice', 'age': 30, 'city': 'NYC'} Upper keys: {'NAME': 'Alice', 'AGE': 30, 'CITY': 'NYC'} Prefixed: {'user_name': 'Alice', 'user_age': 30, 'user_city': 'NYC'} === Transform Both === Raw: {'alice': '85', 'bob': '92', 'charlie': '78'} Clean: {'Alice': 85, 'Bob': 92, 'Charlie': 78} === Conditional Transform === Numbers: {'a': -3, 'b': 5, 'c': -1, 'd': 8} Absolute: {'a': 3, 'b': 5, 'c': 1, 'd': 8} Transformed: {'a': 3, 'b': 10, 'c': 1, 'd': 16} === Computed Keys === By length: {5: 'apple', 6: 'cherry'} By first letter: {'a': 'apple', 'b': 'banana', 'c': 'cherry'}
Apply functions to keys or values: {k.upper(): v*2 for k, v in items}.
Invert a dictionary
Swap keys and values.
# Inverting Dictionaries
print("=== Inverting Dictionary (Swap Keys and Values) ===\n")
# Original dictionary
fruit_to_color = {"apple": "red", "banana": "yellow", "grape": "purple"}
print(f"Original: {fruit_to_color}")
# Invert: color → fruit
color_to_fruit = {v: k for k, v in fruit_to_color.items()}
print(f"Inverted: {color_to_fruit}")
print("\n=== Warning: Duplicate Values ===")
# Dict with duplicate values
grades = {"Alice": "A", "Bob": "B", "Charlie": "A", "Diana": "B"}
print(f"Grades: {grades}")
# Simple invert loses data!
grade_to_student = {v: k for k, v in grades.items()}
print(f"Inverted (data lost!): {grade_to_student}")
print("\n=== Solution: Group by Value ===")
# Collect all keys with same value
from collections import defaultdict
grade_groups = defaultdict(list)
for name, grade in grades.items():
grade_groups[grade].append(name)
print(f"Grouped: {dict(grade_groups)}")
# Comprehension version (more complex)
unique_grades = set(grades.values())
grade_to_students = {
grade: [name for name, g in grades.items() if g == grade]
for grade in unique_grades
}
print(f"Comprehension: {grade_to_students}")
print("\n=== Bidirectional Lookup ===")
# Create both directions
country_code = {"USA": 1, "UK": 44, "Japan": 81}
code_country = {v: k for k, v in country_code.items()}
print(f"Country → Code: {country_code}")
print(f"Code → Country: {code_country}")
# Lookup both ways
country = "Japan"
print(f"\n{country} code: {country_code[country]}")
code = 44
print(f"Code {code}: {code_country[code]}")
fruit_to_color ← {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}
3print("=== Inverting Dictionary (Swap Keys and Values) ===\n")45# Original dictionary #?original6fruit_to_color→ {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'} = {"apple": "red", "banana": "yellow", "grape": "purple"}7print(f"Original: {fruit_to_color{'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}}")89# Invert: color → fruit #?invert10color_to_fruit→ {'red': 'apple', 'yellow': 'banana', 'purple': 'grape'} = {v(empty): k(empty) for k, v in fruit_to_color{'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}.items()} #?invertcomp11print(f"Inverted: {color_to_fruit{'red': 'apple', 'yellow': 'banana', 'purple': 'grape'}}")1213print("\n=== Warning: Duplicate Values ===")1415# Dict with duplicate values #?duplicate16grades→ {'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'} = {"Alice": "A", "Bob": "B", "Charlie": "A", "Diana": "B"} #?dupevalues17print(f"Grades: {grades{'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'}}")1819# Simple invert loses data! #?losedata20grade_to_student→ {'A': 'Charlie', 'B': 'Diana'} = {v(empty): k(empty) for k, v in grades{'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'}.items()}21print(f"Inverted (data lost!): {grade_to_student{'A': 'Charlie', 'B': 'Diana'}}")2223print("\n=== Solution: Group by Value ===")2425# Collect all keys with same value #?groupby26from collections import defaultdict2728grade_groups→ defaultdict(<class 'list'>, {}) = defaultdict(list) #?defaultdict29for name, grade in grades.items():output=== Inverting Dictionary (Swap Keys and Values) === Original: {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'} Inverted: {'red': 'apple', 'yellow': 'banana', 'purple': 'grape'} === Warning: Duplicate Values === Grades: {'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'} Inverted (data lost!): {'A': 'Charlie', 'B': 'Diana'} === Solution: Group by Value ===grade_groups[grade] ← ['Alice']
pass 1 of 428grade_groups = defaultdict(list) #?defaultdict29for nameAlice, gradeA in grades{'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'}.items():30 grade_groups[grade]→ ['Alice'].append(nameAlice)31print(f"Grouped: {dict(grade_groups)}")All 4 passes — pass 1 is the card above pass namegradegrade_groups[grade]1 Alice A [] → ['Alice'] 2 Bob B [] → ['Bob'] 3 Charlie A ['Alice'] → ['Alice', 'Charlie'] 4 Diana B ['Bob'] → ['Bob', 'Diana'] unique_grades ← {'A', 'B'}, grade_to_students ← {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']}
30 grade_groups[grade].append(name)31print(f"Grouped: {dict(grade_groupsdefaultdict(<class 'list'>, {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']}))}")3233# Comprehension version (more complex) #?groupcomp34unique_grades→ {'A', 'B'} = set(grades{'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'}.values())35grade_to_students→ {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']} = {36 grade: [nameDiana for name, g(empty) in grades{'Alice': 'A', 'Bob': 'B', 'Charlie': 'A', 'Diana': 'B'}.items() if g == grade]37 for grade in unique_grades{'A', 'B'}38} #?nestedcomp39print(f"Comprehension: {grade_to_students{'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']}}")4041print("\n=== Bidirectional Lookup ===")4243# Create both directions #?bidirectional44country_code→ {'USA': 1, 'UK': 44, 'Japan': 81} = {"USA": 1, "UK": 44, "Japan": 81}45code_country→ {1: 'USA', 44: 'UK', 81: 'Japan'} = {v(empty): k(empty) for k, v in country_code{'USA': 1, 'UK': 44, 'Japan': 81}.items()} #?codemap4647print(f"Country → Code: {country_code{'USA': 1, 'UK': 44, 'Japan': 81}}")48print(f"Code → Country: {code_country{1: 'USA', 44: 'UK', 81: 'Japan'}}")4950# Lookup both ways51country→ Japan = "Japan"52print(f"\n{countryJapan} code: {country_code[country]81}")53code→ 44 = 4454print(f"Code {code44}: {code_country[code]UK}")55#@help originaloutputGrouped: {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']} Comprehension: {'A': ['Alice', 'Charlie'], 'B': ['Bob', 'Diana']} === Bidirectional Lookup === Country → Code: {'USA': 1, 'UK': 44, 'Japan': 81} Code → Country: {1: 'USA', 44: 'UK', 81: 'Japan'} Japan code: 81 Code 44: UK
{v: k for k, v in d.items()} swaps keys and values.
Exercise: practical.py
Real-world dictionary comprehension patterns