Data Structures

Python Dictionaries

Master Python dictionaries - key-value data structures for fast lookups, with methods, comprehensions, and practical patterns.

Python Dictionaries

Dictionaries are unordered (insertion-ordered since Python 3.7+) collections of key-value pairs. They provide extremely fast lookups by key and are one of Python's most powerful built-in data structures.


Creating Dictionaries

python
# Curly braces
student = {"name": "Alice", "age": 25, "grade": "A"}

# dict() constructor
student = dict(name="Alice", age=25, grade="A")

# From list of tuples
student = dict([("name", "Alice"), ("age", 25), ("grade", "A")])

# From two lists with zip
keys = ["name", "age", "grade"]
values = ["Alice", 25, "A"]
student = dict(zip(keys, values))

# Empty dictionary
empty = {}
empty = dict()

# dict.fromkeys() - all same value
defaults = dict.fromkeys(["a", "b", "c"], 0)
print(defaults)  # {'a': 0, 'b': 0, 'c': 0}

Accessing Values

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

# Bracket notation
print(student["name"])   # Alice

# get() method (safer - returns None if key missing)
print(student.get("name"))      # Alice
print(student.get("email"))     # None
print(student.get("email", "N/A"))  # N/A (default value)

# Check if key exists
print("name" in student)     # True
print("email" in student)    # False
print("Alice" in student.values())  # True

Modifying Dictionaries

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

# Add or update
student["grade"] = "A"         # Add new key
student["age"] = 26            # Update existing key

# update() - merge another dict
student.update({"city": "NYC", "age": 27})
print(student)
# {'name': 'Alice', 'age': 27, 'grade': 'A', 'city': 'NYC'}

# Merge operator | (Python 3.9+)
defaults = {"theme": "dark", "lang": "en"}
preferences = {"theme": "light", "font": "Arial"}
merged = defaults | preferences
print(merged)  # {'theme': 'light', 'lang': 'en', 'font': 'Arial'}

# |= operator (update in place)
defaults |= preferences
print(defaults)  # {'theme': 'light', 'lang': 'en', 'font': 'Arial'}

# setdefault() - set only if key doesn't exist
student.setdefault("country", "US")
print(student["country"])  # US
student.setdefault("country", "UK")  # Doesn't change
print(student["country"])  # US

Removing Elements

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

# pop() - remove and return value
age = student.pop("age")
print(age)       # 25
print(student)   # {'name': 'Alice', 'grade': 'A', 'city': 'NYC'}

# pop with default (no error if key missing)
email = student.pop("email", "not found")
print(email)  # not found

# popitem() - remove last inserted pair
last = student.popitem()
print(last)      # ('city', 'NYC')

# del
del student["grade"]
print(student)   # {'name': 'Alice'}

# clear() - remove all
student.clear()
print(student)   # {}

Iterating Over Dictionaries

python
scores = {"Alice": 92, "Bob": 85, "Charlie": 78, "Diana": 95}

# Iterate over keys (default)
for name in scores:
    print(name)

# Iterate over values
for score in scores.values():
    print(score)

# Iterate over key-value pairs
for name, score in scores.items():
    print(f"{name}: {score}")

# Sorted iteration
for name in sorted(scores):
    print(f"{name}: {scores[name]}")

# Sort by value
for name, score in sorted(scores.items(), key=lambda x: x[1], reverse=True):
    print(f"{name}: {score}")
# Diana: 95
# Alice: 92
# Bob: 85
# Charlie: 78

Dictionary Comprehensions

python
# Basic comprehension
squares = {x: x**2 for x in range(6)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# With condition
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# Transform values
prices = {"apple": 1.20, "banana": 0.50, "cherry": 2.00}
discounted = {item: round(price * 0.9, 2) for item, price in prices.items()}
print(discounted)  # {'apple': 1.08, 'banana': 0.45, 'cherry': 1.8}

# Swap keys and values
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped)  # {1: 'a', 2: 'b', 3: 'c'}

# Word frequency
text = "the cat sat on the mat the cat"
word_count = {word: text.split().count(word) for word in set(text.split())}
print(word_count)  # {'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1}

Nested Dictionaries

python
students = {
    "alice": {
        "age": 25,
        "grades": {"math": 92, "science": 88, "english": 95}
    },
    "bob": {
        "age": 22,
        "grades": {"math": 78, "science": 82, "english": 85}
    }
}

# Access nested values
print(students["alice"]["grades"]["math"])  # 92

# Iterate nested
for name, info in students.items():
    avg = sum(info["grades"].values()) / len(info["grades"])
    print(f"{name.title()} β€” Age: {info['age']}, Average: {avg:.1f}")

Useful Dictionary Methods

MethodDescription
get(key, default)Get value safely
keys()Return all keys
values()Return all values
items()Return key-value pairs
update(dict2)Merge another dict
pop(key, default)Remove and return value
popitem()Remove last inserted pair
setdefault(key, val)Set if not exists
clear()Remove all items
copy()Shallow copy

Common Patterns

Counting with Dictionaries

python
text = "hello world hello python world hello"
words = text.split()

# Manual counting
counts = {}
for word in words:
    counts[word] = counts.get(word, 0) + 1
print(counts)  # {'hello': 3, 'world': 2, 'python': 1}

# Using Counter (preferred)
from collections import Counter
counts = Counter(words)
print(counts.most_common(2))  # [('hello', 3), ('world', 2)]

Grouping Data

python
students = [
    ("Alice", "Engineering"),
    ("Bob", "Marketing"),
    ("Charlie", "Engineering"),
    ("Diana", "Marketing"),
    ("Eve", "Science")
]

# Group by department
from collections import defaultdict
departments = defaultdict(list)
for name, dept in students:
    departments[dept].append(name)

for dept, names in departments.items():
    print(f"{dept}: {', '.join(names)}")
# Engineering: Alice, Charlie
# Marketing: Bob, Diana
# Science: Eve

Caching / Memoization

python
cache = {}

def fibonacci(n):
    if n in cache:
        return cache[n]
    if n <= 1:
        return n
    result = fibonacci(n - 1) + fibonacci(n - 2)
    cache[n] = result
    return result

print(fibonacci(100))  # 354224848179261915075 (instant!)

Summary

  • Dictionaries store key-value pairs with fast O(1) lookups
  • Keys must be hashable (strings, numbers, tuples); values can be anything
  • Use get() for safe access, in for membership checks
  • update() or | (Python 3.9+) to merge dictionaries
  • Dictionary comprehensions for concise creation and transformation
  • Use Counter for counting, defaultdict for grouping
  • Dictionaries are insertion-ordered (Python 3.7+)

Next, we'll learn about Python sets.