intermediate Step 6 of 20

Dictionaries and Sets

Python Programming

Dictionaries and Sets

Dictionaries and sets are two of Python's most powerful built-in data structures. A dictionary (dict) is an unordered collection of key-value pairs that provides extremely fast lookups by key. A set is an unordered collection of unique elements that supports mathematical set operations like union, intersection, and difference. Both are implemented using hash tables internally, which gives them O(1) average-case performance for lookups, insertions, and deletions.

Creating and Using Dictionaries

# Creating dictionaries
person = {
    "name": "Alice",
    "age": 30,
    "city": "New York",
    "hobbies": ["reading", "coding"]
}

# Alternative creation methods
empty = {}
from_tuples = dict([("a", 1), ("b", 2)])
from_keys = dict.fromkeys(["x", "y", "z"], 0)  # {"x": 0, "y": 0, "z": 0}

# Accessing values
print(person["name"])           # "Alice"
print(person.get("age"))        # 30
print(person.get("email", "N/A"))  # "N/A" (default if key missing)
# print(person["email"])        # KeyError!

# Adding and modifying
person["email"] = "alice@example.com"   # Add new key
person["age"] = 31                      # Update existing key
person.update({"city": "Boston", "phone": "555-0123"})

# Removing
del person["phone"]
email = person.pop("email")           # Remove and return value
last_item = person.popitem()           # Remove and return last pair

Iterating Over Dictionaries

scores = {"Alice": 95, "Bob": 87, "Charlie": 92}

# 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}")

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

# Filtering with comprehension
high_scores = {name: score for name, score in scores.items() if score >= 90}
# {"Alice": 95, "Charlie": 92}

Nested Dictionaries

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

# Accessing nested values
print(students["alice"]["grades"]["math"])  # 95

# Safely accessing nested values
def safe_get(data, *keys, default=None):
    for key in keys:
        if isinstance(data, dict):
            data = data.get(key, default)
        else:
            return default
    return data

print(safe_get(students, "alice", "grades", "math"))       # 95
print(safe_get(students, "charlie", "grades", "math"))      # None

Sets

Sets are unordered collections of unique elements. They are perfect for removing duplicates, membership testing, and mathematical set operations.

# Creating sets
fruits = {"apple", "banana", "cherry"}
numbers = set([1, 2, 2, 3, 3, 3])  # {1, 2, 3} — duplicates removed
empty_set = set()  # NOT {} — that creates an empty dict

# Adding and removing
fruits.add("date")
fruits.discard("banana")   # No error if not found
fruits.remove("cherry")    # KeyError if not found

# Set operations
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}

print(a | b)    # Union: {1, 2, 3, 4, 5, 6, 7, 8}
print(a & b)    # Intersection: {4, 5}
print(a - b)    # Difference: {1, 2, 3}
print(a ^ b)    # Symmetric difference: {1, 2, 3, 6, 7, 8}

# Subset and superset
print({1, 2} <= {1, 2, 3})   # True (subset)
print({1, 2, 3} >= {1, 2})   # True (superset)

# Practical: remove duplicates while preserving order
items = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
seen = set()
unique = []
for item in items:
    if item not in seen:
        seen.add(item)
        unique.append(item)
print(unique)  # [3, 1, 4, 5, 9, 2, 6]

# Set comprehension
evens = {x for x in range(20) if x % 2 == 0}
Pro tip: Use dict.get(key, default) instead of dict[key] when the key might not exist — it returns the default value instead of raising a KeyError. For counting occurrences, use collections.Counter which is a specialized dictionary subclass.

Key Takeaways

  • Dictionaries store key-value pairs with O(1) average lookup time; keys must be hashable (strings, numbers, tuples).
  • Use .get(key, default) for safe access and .items() to iterate over key-value pairs.
  • Sets store unique elements and support union (|), intersection (&), difference (-), and symmetric difference (^).
  • Dictionary and set comprehensions provide concise syntax for creating filtered or transformed collections.
  • Both dicts and sets are implemented as hash tables, making them extremely fast for lookups and membership tests.