You're building a phone book. Given a name, you need the phone number instantly. Lists require searching through every entry. Dictionaries give you direct lookup by key - O(1) instead of O(n).

Create a phone book

Store name-to-number associations.

phone_book.py
def main():
    # Create a phone book dictionary
    phone_book = {}
    
    print("=== Building Phone Book ===")
    
    # Add contacts
    phone_book["Alice"] = "555-1234"
    print(f"Added Alice: {phone_book}")
    
    phone_book["Bob"] = "555-5678"
    print(f"Added Bob: {phone_book}")
    
    phone_book["Carol"] = "555-9999"
    print(f"Added Carol: {phone_book}")
    
    # Add more contacts
    phone_book["David"] = "555-1111"
    phone_book["Eve"] = "555-2222"
    phone_book["Frank"] = "555-3333"
    print(f"\nWith more contacts: {phone_book}")
    
    print("\n=== Phone Book Contents ===")
    print(f"Total contacts: {len(phone_book)}")
    
    # Look up a number
    name = "Bob"
    number = phone_book[name]
    print(f"\n{name}'s number: {number}")
    
    # Display all contacts
    print("\n=== All Contacts ===")
    for name, number in phone_book.items():
        print(f"{name}: {number}")

main()

{key: value} creates a dict. Use d[key] to access values.

dict Key-value pairs with O(1) lookup. Keys must be unique and hashable.

Look up a contact

Retrieve a value by its key.

lookup.py
def main():
    inventory = {
        "Apples": 50,
        "Bananas": 30,
        "Oranges": 25,
        "Grapes": 40
    }
    
    print("=== Store Inventory ===")
    print(inventory)
    
    # Look up existing item
    item = 
    
    print("\n=== Inventory Lookup ===")
    print(f"Looking for: {item}")
    
    # UNSAFE: Direct access raises KeyError if missing!
    # stock = inventory[item]  # Would crash if item not found
    
    # SAFE: Use .get() method
    stock = inventory.get(item)
    
    if stock is not None:
        print(f"In stock: {stock} units")
        if stock < 35:
            print("⚠️ Low stock - consider reordering!")
    else:
        print("❌ Item not found in inventory!")
        print(f"Available items: {list(inventory.keys())}")
    
    # Using .get() with default value
    print("\n=== Using .get() with default ===")
    check_items = ["Apples", "Mangoes", "Oranges", "Pears"]
    
    for check_item in check_items:
        qty = inventory.get(check_item, 0)  # 0 if not found
        status = f"✓ {qty} in stock" if qty > 0 else "✗ Not available"
        print(f"{check_item}: {status}")

main()
def main():
    inventory = {
        "Apples": 50,
        "Bananas": 30,
        "Oranges": 25,
        "Grapes": 40
    }
    
    print("=== Store Inventory ===")
    print(inventory)
    
    # Look up existing item
    item = 
    
    print("\n=== Inventory Lookup ===")
    print(f"Looking for: {item}")
    
    # UNSAFE: Direct access raises KeyError if missing!
    # stock = inventory[item]  # Would crash if item not found
    
    # SAFE: Use .get() method
    stock = inventory.get(item)
    
    if stock is not None:
        print(f"In stock: {stock} units")
        if stock < 35:
            print("⚠️ Low stock - consider reordering!")
    else:
        print("❌ Item not found in inventory!")
        print(f"Available items: {list(inventory.keys())}")
    
    # Using .get() with default value
    print("\n=== Using .get() with default ===")
    check_items = ["Apples", "Mangoes", "Oranges", "Pears"]
    
    for check_item in check_items:
        qty = inventory.get(check_item, 0)  # 0 if not found
        status = f"✓ {qty} in stock" if qty > 0 else "✗ Not available"
        print(f"{check_item}: {status}")

main()

d[key] raises KeyError if missing. Use d.get(key) for safe access.

get Safe lookup: `d.get(key)` returns None if missing. `d.get(key, default)` for default.

Update an entry

Change the value associated with a key.

update_entry.py
def main():
    inventory = {
        "Apples": 50,
        "Bananas": 30,
        "Oranges": 25
    }
    
    print("=== Initial Inventory ===")
    print(inventory)
    
    # Update: Restock apples
    item = "Apples"
    add_amount = 20
    
    old_stock = inventory[item]
    inventory[item] = old_stock + add_amount  # Direct update
    
    print("\n=== After Restocking ===")
    print(f"{item}: {old_stock} → {inventory[item]}")
    print(inventory)
    
    # Sell some items
    item = "Bananas"
    sold = 5
    inventory[item] -= sold
    print(f"\nSold {sold} {item}")
    print(inventory)
    
    # Word frequency counter
    print("\n=== Word Frequency Counter ===")
    text = "apple banana apple orange apple banana grape"
    words = text.split()
    
    word_count = {}
    
    for word in words:
        # Get current count (0 if not seen), add 1
        word_count[word] = word_count.get(word, 0) + 1
    
    print(f'Text: "{text}"')
    print(f"Word counts: {word_count}")
    
    # Pythonic alternative: collections.Counter
    from collections import Counter
    print(f"Using Counter: {dict(Counter(words))}")

main()

d[key] = value updates if exists, adds if new.

Check if key exists

Test whether a key is in the dict before accessing.

check_key.py
def main():
    user_passwords = {
        "alice": "pass123",
        "bob": "secret456",
        "carol": "hunter2"
    }
    
    print("=== Login System ===")
    print(f"Registered users: {list(user_passwords.keys())}")
    
    # Login attempt
    username = 
    password = "secret456"
    
    print("\n=== Login Attempt ===")
    print(f"Username: {username}")
    
    # Check if user exists
    if username in user_passwords:
        print("✓ User found")
        
        # Verify password
        correct_password = user_passwords[username]
        if correct_password == password:
            print("✓ Password correct")
            print("🎉 Login successful!")
        else:
            print("✗ Incorrect password")
    else:
        print("✗ User not found")
        print("Would you like to register?")
    
    # Check if value exists (less common)
    print("\n=== Security Check ===")
    weak_password = "pass123"
    
    if weak_password in user_passwords.values():
        print("⚠️ Someone is using a weak password!")
        
        # Find which user (need to iterate)
        for user, pwd in user_passwords.items():
            if pwd == weak_password:
                print(f"User with weak password: {user}")

main()
def main():
    user_passwords = {
        "alice": "pass123",
        "bob": "secret456",
        "carol": "hunter2"
    }
    
    print("=== Login System ===")
    print(f"Registered users: {list(user_passwords.keys())}")
    
    # Login attempt
    username = 
    password = "secret456"
    
    print("\n=== Login Attempt ===")
    print(f"Username: {username}")
    
    # Check if user exists
    if username in user_passwords:
        print("✓ User found")
        
        # Verify password
        correct_password = user_passwords[username]
        if correct_password == password:
            print("✓ Password correct")
            print("🎉 Login successful!")
        else:
            print("✗ Incorrect password")
    else:
        print("✗ User not found")
        print("Would you like to register?")
    
    # Check if value exists (less common)
    print("\n=== Security Check ===")
    weak_password = "pass123"
    
    if weak_password in user_passwords.values():
        print("⚠️ Someone is using a weak password!")
        
        # Find which user (need to iterate)
        for user, pwd in user_passwords.items():
            if pwd == weak_password:
                print(f"User with weak password: {user}")

main()

key in d is O(1) - use it to avoid KeyError.

in Membership test: `key in d`. Returns True/False in O(1) time.

Iterate through entries

Loop through keys, values, or key-value pairs.

iterate_dict.py
def main():
    prices = {
        "Coffee": 4.50,
        "Tea": 3.00,
        "Juice": 5.25,
        "Water": 1.50,
        "Soda": 2.75
    }
    
    print("=== Café Menu ===\n")
    
    # Method 1: Iterate keys only
    print("1. Keys only:")
    for item in prices:  # Or: prices.keys()
        print(f"   • {item}")
    
    # Method 2: Iterate values only
    print("\n2. Values only:")
    total = 0
    for price in prices.values():
        total += price
        print(f"   ${price:.2f}")
    print(f"   Total: ${total:.2f}")
    
    # Method 3: Iterate both with .items() - MOST COMMON
    print("\n3. Keys and Values (.items()):")
    for item, price in prices.items():
        print(f"   {item:<10} ${price:.2f}")
    
    # Method 4: Enumerate with items (if you need index)
    print("\n4. With index:")
    for i, (item, price) in enumerate(prices.items(), 1):
        print(f"   {i}. {item}: ${price:.2f}")
    
    # Find min and max priced items
    print("\n=== Price Analysis ===")
    
    # Pythonic: use min/max with key parameter
    cheapest = min(prices, key=prices.get)
    expensive = max(prices, key=prices.get)
    
    print(f"Cheapest: {cheapest} (${prices[cheapest]:.2f})")
    print(f"Most expensive: {expensive} (${prices[expensive]:.2f})")
    
    # Average price
    avg = sum(prices.values()) / len(prices)
    print(f"Average price: ${avg:.2f}")

main()

Use d.keys(), d.values(), or d.items() for different views.

Exercise: dict_comprehension.py

Create dictionaries with comprehension syntax