Dictionaries and Sets in Python
Understanding Mapping and Collection Types
Dictionaries and sets are two powerful collection types in Python, each with unique features and use cases. While they both use curly braces in their syntax, they serve very different purposes.
Dictionaries are mapping types that store key-value pairs, while sets are unordered collections of unique elements with efficient membership testing.
# Dictionary stores key-value pairs person = {"name": "Alice", "age": 30, "city": "New York"} # Set stores unique values fruits = {"apple", "banana", "cherry"} # Both use curly braces but serve different purposes print(person["name"]) # Access by key: "Alice" print("banana" in fruits) # Membership test: True
Python Dictionaries in Detail
Dictionary Creation and Basics
Dictionaries are Python's built-in mapping type that stores key-value pairs. Each key must be unique and immutable.
They're created with curly braces {}
or the dict()
constructor.
# Ways to create dictionaries empty_dict = {} person = {"name": "Alice", "age": 30} # Using dict constructor config = dict(host="localhost", port=8080) # From list of tuples items = dict([("apple", 1.5), ("banana", 0.75)]) # From iterables with keys and values keys = ["a", "b", "c"] values = [1, 2, 3] combined = dict(zip(keys, values)) # {'a': 1, 'b': 2, 'c': 3} # Dictionary comprehension squares = {x: x**2 for x in range(6)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Accessing and Modifying Dictionaries
Python offers multiple ways to access, add, update, and remove dictionary items.
# Accessing dictionary values person = {"name": "Alice", "age": 30, "city": "New York"} # By key print(person["name"]) # Alice # print(person["job"]) # KeyError if key doesn't exist # get() method print(person.get("name")) # Alice print(person.get("job")) # None (default) print(person.get("job", "N/A")) # N/A (custom default) # Adding or updating items person["job"] = "Engineer" # Add new key-value pair person["age"] = 31 # Update existing value # update() method - merge dictionaries person.update({"job": "Developer", "email": "alice@example.com"}) # Removing items removed_value = person.pop("city") # Returns "New York" # person.pop("country") # KeyError if key doesn't exist removed_item = person.popitem() # Removes and returns last item as tuple del person["job"] # Delete key-value pair # Clear all items person.clear() # {}
Dictionary Methods and Operations
Dictionaries provide several useful methods for working with keys, values, and items.
# Dictionary views person = {"name": "Alice", "age": 30, "city": "New York"} # Get all keys keys = person.keys() # dict_keys(['name', 'age', 'city']) # Get all values values = person.values() # dict_values(['Alice', 30, 'New York']) # Get all key-value pairs as tuples items = person.items() # dict_items([('name', 'Alice'), ('age', 30), ('city', 'New York')]) # These views are dynamic, they update when dictionary changes person["email"] = "alice@example.com" print(keys) # Now includes 'email' # Checking if a key exists print("name" in person) # True print("job" in person) # False # Copy a dictionary person_copy = person.copy() person_deep_copy = dict(person) # setdefault() - get value or set default score = person.setdefault("score", 0) # Adds {"score": 0}
Dictionary Iteration
There are several ways to iterate through dictionaries in Python.
# Iterating through a dictionary person = {"name": "Alice", "age": 30, "city": "New York"} # Iterate through keys (default) for key in person: print(key, "->", person[key]) # Iterate through values for value in person.values(): print(value) # Iterate through keys for key in person.keys(): print(key) # Iterate through key-value pairs for key, value in person.items(): print(f"{key}: {value}") # Sorted iteration (by keys) for key in sorted(person.keys()): print(f"{key}: {person[key]}")
Dictionary Comprehensions
Dictionary comprehensions provide a concise way to create dictionaries based on existing iterables.
# Basic dictionary 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 conditions 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 existing dictionary person = {"name": "Alice", "age": 30, "city": "New York"} upper_dict = {k.upper(): v for k, v in person.items()} print(upper_dict) # {'NAME': 'Alice', 'AGE': 30, 'CITY': 'New York'} # From two lists fruits = ["apple", "banana", "cherry"] prices = [1.2, 0.9, 2.5] fruit_prices = {f: p for f, p in zip(fruits, prices)} print(fruit_prices) # {'apple': 1.2, 'banana': 0.9, 'cherry': 2.5}
Nested Dictionaries
Dictionary values can be any Python object, including other dictionaries.
# Nested dictionaries users = { "alice": { "name": "Alice Smith", "email": "alice@example.com", "age": 30 }, "bob": { "name": "Bob Johnson", "email": "bob@example.com", "age": 25 } } # Accessing nested values print(users["alice"]["email"]) # alice@example.com # Modifying nested values users["alice"]["age"] = 31 # Adding nested dictionaries users["charlie"] = {"name": "Charlie Brown", "email": "charlie@example.com", "age": 35} # Iterating through nested dictionaries for username, user_info in users.items(): print(f"User: {username}") for key, value in user_info.items(): print(f" {key}: {value}") # Deep vs. shallow copy import copy users_shallow = users.copy() users_deep = copy.deepcopy(users)
Python Sets in Detail
Set Creation and Basics
Sets are unordered collections of unique elements in Python. They are useful for membership testing, removing duplicates, and performing mathematical set operations like unions and intersections.
# Ways to create sets empty_set = set() # Empty set (cannot use {} as that creates an empty dict) fruits = {"apple", "banana", "cherry"} # Set with initial values # From other iterables vowels = set("aeiou") # {'a', 'e', 'i', 'o', 'u'} numbers = set([1, 2, 2, 3, 4, 4, 5]) # {1, 2, 3, 4, 5} (duplicates removed) # Set comprehension even_numbers = {x for x in range(10) if x % 2 == 0} # {0, 2, 4, 6, 8} # Properties of sets # - Sets are unordered (items have no index) # - Sets contain unique items only # - Sets can only contain immutable elements (no lists/dicts) # - Sets themselves are mutable (can be changed)
Set Operations
Sets support a variety of operations for adding, removing, and modifying elements.
# Adding elements colors = {"red", "green"} colors.add("blue") # {"red", "green", "blue"} # Adding duplicate elements has no effect colors.add("red") # Still {"red", "green", "blue"} # Add multiple elements colors.update(["yellow", "purple"]) # {"red", "green", "blue", "yellow", "purple"} colors.update({"orange", "pink"}, ["black", "white"]) # Can combine multiple iterables # Removing elements colors.remove("red") # Removes "red" from the set # colors.remove("brown") # KeyError if element doesn't exist colors.discard("green") # Removes "green" from the set colors.discard("gray") # No error if element doesn't exist popped = colors.pop() # Removes and returns an arbitrary element # Remove all elements colors.clear() # {}
Set Methods and Mathematical Operations
Sets in Python support various mathematical set operations like union, intersection, and difference.
# Set operations A = {1, 2, 3, 4, 5} B = {4, 5, 6, 7, 8} # Union: all elements from both sets print(A | B) # {1, 2, 3, 4, 5, 6, 7, 8} print(A.union(B)) # Same as above # Intersection: elements common to both sets print(A & B) # {4, 5} print(A.intersection(B)) # Same as above # Difference: elements in A but not in B print(A - B) # {1, 2, 3} print(A.difference(B)) # Same as above # Symmetric difference: elements in either A or B but not both print(A ^ B) # {1, 2, 3, 6, 7, 8} print(A.symmetric_difference(B)) # Same as above # Update operations (modify the original set) C = {1, 2, 3} D = {3, 4, 5} C.update(D) # Union update (C now equals {1, 2, 3, 4, 5}) C.intersection_update(D) # Intersection update (C now equals {3, 4, 5}) C.difference_update(D) # Difference update (C now equals {}) C = {1, 2, 3} C.symmetric_difference_update(D) # Symmetric difference update (C now equals {1, 2, 4, 5})
Set Relationships and Comparisons
Sets can be compared to check for relationships like subsets, supersets, and equality.
# Subset and superset relationships A = {1, 2, 3} B = {1, 2, 3, 4, 5} C = {1, 2, 3} D = {6, 7, 8} # Subset: all elements of A are in B print(A.issubset(B)) # True print(A <= B) # True (subset operator) print(A < B) # True (proper subset: A ⊂ B, A ≠ B) # Superset: all elements of B are in A print(B.issuperset(A)) # True print(B >= A) # True (superset operator) print(B > A) # True (proper superset: B ⊃ A, B ≠ A) # Equality: A and C have the same elements print(A == C) # True print(A == B) # False # Disjoint: A and D have no elements in common print(A.isdisjoint(D)) # True print(A.isdisjoint(B)) # False (they share elements)
Practical Applications of Sets
Sets are incredibly useful for many common programming tasks, especially those involving unique values.
# Remove duplicates from a list numbers = [1, 2, 2, 3, 4, 4, 5] unique_numbers = list(set(numbers)) # [1, 2, 3, 4, 5] (order may vary) # Membership testing (very efficient for large collections) fruits = {"apple", "banana", "cherry"} print("banana" in fruits) # True print("orange" in fruits) # False # Find common elements between collections list1 = [1, 2, 3, 4] list2 = [3, 4, 5, 6] common = set(list1) & set(list2) # {3, 4} # Find unique elements in collections only_in_list1 = set(list1) - set(list2) # {1, 2} only_in_list2 = set(list2) - set(list1) # {5, 6} # Count unique items text = "Mississippi" unique_chars = set(text) # {'M', 'i', 's', 'p'} print(len(unique_chars)) # 4 # Find all unique combinations import itertools dice1 = {1, 2, 3, 4, 5, 6} dice2 = {1, 2, 3, 4, 5, 6} combinations = {(x, y) for x in dice1 for y in dice2} # 36 unique combinations
Comparing Dictionaries and Sets
Dictionaries and sets share some similarities but serve different purposes. Both use hash tables internally for fast lookups.
Feature | Dictionaries | Sets |
---|---|---|
Purpose | Store key-value pairs | Store unique elements |
Syntax | {key: value} |
{element} |
Empty Collection | {} |
set() (not {} ) |
Lookup | dict[key] or dict.get(key) |
element in set |
Content Constraints | Keys must be immutable, values can be any type | Elements must be immutable |
Common Operations | Key lookup, updating values | Union, intersection, difference |
Time Complexity | O(1) for lookup, insertion, deletion | O(1) for lookup, insertion, deletion |
Ordered | Yes, since Python 3.7 | No (unordered) |
Practice Exercises
Try these exercises to solidify your understanding of dictionaries and sets:
- Create a function that counts the frequency of each word in a text and returns a dictionary.
- Create a function that finds all common elements between two lists using sets.
- Implement a simple phone book using a dictionary and allow users to add, search, and delete contacts.
- Use a set to filter duplicate entries from a list of email addresses.
- Create a nested dictionary to represent a simple JSON-like structure of user data.