Data Structures
Working with lists, tuples, dictionaries, and sets
Introduction
Data structures allow you to organize and store collections of data efficiently. Python provides four fundamental built-in data structures: lists (ordered, mutable), tuples (ordered, immutable), dictionaries (key-value pairs), and sets (unordered, unique elements). Each has its own characteristics and use cases, making Python versatile for handling different types of data.
Quick Comparison
| Data Structure | Ordered | Mutable | Use Case |
|---|---|---|---|
| List | ✓ Yes | ✓ Yes | Ordered collection of items |
| Tuple | ✓ Yes | ✗ No | Immutable sequence of items |
| Dictionary | ✓ Yes* | ✓ Yes | Key-value pairs |
| Set | ✗ No | ✓ Yes | Unique unordered collection |
*Dictionaries maintain insertion order (Python 3.7+)
Lists
Lists are ordered, mutable collections of items. They're one of the most commonly used data structures in Python.
Creating Lists
# Empty list numbers = [] names = list() # List with items fruits = ["apple", "banana", "orange"] numbers = [1, 2, 3, 4, 5] mixed = [1, "hello", 3.14, True] # Can contain different types # List from range numbers = list(range(5)) # [0, 1, 2, 3, 4] numbers = list(range(1, 6)) # [1, 2, 3, 4, 5]
Accessing List Items
fruits = ["apple", "banana", "orange", "grape"] # Access by index (0-based) first = fruits[0] # "apple" second = fruits[1] # "banana" last = fruits[-1] # "grape" (negative indexing) # Slicing first_two = fruits[0:2] # ["apple", "banana"] last_two = fruits[-2:] # ["orange", "grape"] middle = fruits[1:3] # ["banana", "orange"] all_items = fruits[:] # Copy of entire list
Modifying Lists
fruits = ["apple", "banana"]
# Add items
fruits.append("orange") # ["apple", "banana", "orange"]
fruits.insert(1, "grape") # ["apple", "grape", "banana", "orange"]
fruits.extend(["mango", "kiwi"]) # Add multiple items
# Remove items
fruits.remove("banana") # Remove first occurrence
fruits.pop() # Remove and return last item
fruits.pop(0) # Remove and return item at index 0
del fruits[1] # Delete item at index 1
# Modify items
fruits[0] = "pear" # Replace item at index 0List Methods and Operations
numbers = [3, 1, 4, 1, 5, 9, 2] # Common methods len(numbers) # 7 (length) numbers.count(1) # 2 (count occurrences) numbers.index(4) # 2 (first index of value) numbers.sort() # Sort in place: [1, 1, 2, 3, 4, 5, 9] numbers.reverse() # Reverse in place sorted(numbers) # Return sorted copy (doesn't modify original) # Concatenation list1 = [1, 2, 3] list2 = [4, 5, 6] combined = list1 + list2 # [1, 2, 3, 4, 5, 6] # Repetition repeated = [0] * 5 # [0, 0, 0, 0, 0] # Membership "apple" in fruits # True "grape" not in fruits # True
List Comprehension (Advanced)
List comprehensions provide a concise way to create lists:
# Traditional way
squares = []
for x in range(10):
squares.append(x ** 2)
# List comprehension (more Pythonic)
squares = [x ** 2 for x in range(10)] # [0, 1, 4, 9, 16, ...]
# With condition
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]Tuples
Tuples are ordered, immutable collections. Once created, you cannot modify them. They're useful for data that shouldn't change, like coordinates or database records.
Creating Tuples
# Empty tuple (rare)
empty = ()
empty = tuple()
# Tuple with items
coordinates = (10, 20)
point = 10, 20 # Parentheses optional (but recommended)
person = ("Alice", 30, "Engineer")
# Single item tuple (note the comma!)
single = (5,) # Tuple
not_tuple = (5) # This is just an integer!Accessing and Using Tuples
point = (10, 20)
# Access by index (same as lists)
x = point[0] # 10
y = point[1] # 20
# Slicing (returns new tuple)
first_two = point[:1] # (10,)
# Unpacking
x, y = point # x = 10, y = 20
# Multiple assignment
name, age, job = ("Alice", 30, "Engineer")
# Tuple methods
point.count(10) # Count occurrences
point.index(20) # Find index of value
# Cannot modify (immutable)
# point[0] = 5 # This will cause TypeError!When to Use Tuples
✓ Good for Tuples
- Coordinates (x, y)
- RGB color values
- Database records
- Function return values
- Dictionary keys (immutable requirement)
Use Lists Instead
- When items need to change
- When you need to add/remove items
- For dynamic collections
- When order matters but items change
Dictionaries
Dictionaries store data as key-value pairs. They're incredibly useful for organizing data with meaningful relationships, like a contact list or configuration settings.
Creating Dictionaries
# Empty dictionary
person = {}
person = dict()
# Dictionary with key-value pairs
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
# Using dict() constructor
person = dict(name="Alice", age=30, city="New York")
# Dictionary with different value types
info = {
"name": "Bob",
"scores": [85, 90, 88],
"active": True,
"balance": 1250.50
}Accessing Dictionary Values
person = {"name": "Alice", "age": 30}
# Access by key
name = person["name"] # "Alice"
age = person["age"] # 30
# Using get() (safer - returns None if key doesn't exist)
name = person.get("name") # "Alice"
email = person.get("email") # None (key doesn't exist)
email = person.get("email", "N/A") # "N/A" (default value)
# Check if key exists
if "name" in person:
print(person["name"])
# Keys must be immutable (strings, numbers, tuples)
# Lists cannot be keys!Modifying Dictionaries
person = {"name": "Alice", "age": 30}
# Add or update items
person["city"] = "New York" # Add new key-value
person["age"] = 31 # Update existing value
person.update({"city": "Boston", "job": "Engineer"}) # Update multiple
# Remove items
del person["age"] # Remove key-value pair
city = person.pop("city") # Remove and return value
person.popitem() # Remove and return last item (Python 3.7+)
person.clear() # Remove all itemsDictionary Methods
person = {"name": "Alice", "age": 30, "city": "New York"}
# Get keys, values, items
person.keys() # dict_keys(['name', 'age', 'city'])
person.values() # dict_values(['Alice', 30, 'New York'])
person.items() # dict_items([('name', 'Alice'), ('age', 30), ...])
# Convert to lists (if needed)
list(person.keys()) # ['name', 'age', 'city']
list(person.values()) # ['Alice', 30, 'New York']
# Length
len(person) # 3
# Iterating
for key in person:
print(key, person[key])
for key, value in person.items():
print(key, value)Nested Dictionaries
Dictionaries can contain other dictionaries, lists, and any data type:
students = {
"alice": {
"age": 20,
"grades": [85, 90, 88],
"active": True
},
"bob": {
"age": 21,
"grades": [78, 82, 80],
"active": True
}
}
# Access nested values
alice_age = students["alice"]["age"] # 20
alice_first_grade = students["alice"]["grades"][0] # 85Sets
Sets are unordered collections of unique elements. They're perfect for removing duplicates, membership testing, and mathematical set operations.
Creating Sets
# Empty set (use set(), not {})
numbers = set()
# numbers = {} # This creates a dictionary, not a set!
# Set with items
fruits = {"apple", "banana", "orange"}
numbers = {1, 2, 3, 4, 5}
# From a list (removes duplicates)
unique = set([1, 2, 2, 3, 3, 3]) # {1, 2, 3}
# Set comprehension
squares = {x ** 2 for x in range(5)} # {0, 1, 4, 9, 16}Set Operations
fruits = {"apple", "banana", "orange"}
# Adding and removing
fruits.add("grape") # {"apple", "banana", "orange", "grape"}
fruits.remove("banana") # Removes "banana" (raises error if not found)
fruits.discard("mango") # Safe remove (no error if not found)
fruits.pop() # Remove and return arbitrary element
fruits.clear() # Remove all elements
# Set operations
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set1.union(set2) # {1, 2, 3, 4, 5, 6} (all unique elements)
set1 | set2 # Same as union
set1.intersection(set2) # {3, 4} (common elements)
set1 & set2 # Same as intersection
set1.difference(set2) # {1, 2} (in set1 but not set2)
set1 - set2 # Same as difference
set1.symmetric_difference(set2) # {1, 2, 5, 6} (elements in either but not both)
set1 ^ set2 # Same as symmetric_differenceSet Methods
numbers = {1, 2, 3, 4, 5}
# Membership testing (very fast!)
2 in numbers # True
10 in numbers # False
# Size
len(numbers) # 5
# Set comparisons
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4}
set1.issubset(set2) # True (all elements of set1 in set2)
set1 <= set2 # Same
set2.issuperset(set1) # True (set2 contains all of set1)
set2 >= set1 # Same
set1.isdisjoint({5, 6}) # True (no common elements)Common Set Use Cases
# Remove duplicates from a list
numbers = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(numbers)) # [1, 2, 3, 4]
# Fast membership testing
visited = set()
visited.add("page1")
if "page1" in visited: # Very fast lookup!
print("Already visited")
# Finding common elements
list1 = [1, 2, 3, 4]
list2 = [3, 4, 5, 6]
common = set(list1) & set(list2) # {3, 4}Practical Examples
Example: Student Grade Tracker
# Using a dictionary to track student grades
students = {
"Alice": [85, 90, 88],
"Bob": [78, 82, 80],
"Charlie": [92, 95, 93]
}
# Add a new grade
students["Alice"].append(87)
# Calculate average grade
def average_grades(student_name):
grades = students[student_name]
return sum(grades) / len(grades)
# Get all student names (keys)
names = list(students.keys())
# Find students with average above 90
top_students = [
name for name in students
if average_grades(name) > 90
]Example: Removing Duplicates and Finding Common Items
# Two shopping lists
list1 = ["apple", "banana", "orange", "milk", "bread"]
list2 = ["banana", "milk", "cheese", "yogurt"]
# Convert to sets for operations
set1 = set(list1)
set2 = set(list2)
# Items to buy (all unique items)
to_buy = set1 | set2 # Union
# Items in both lists
common = set1 & set2 # Intersection: {"banana", "milk"}
# Items only in first list
only_list1 = set1 - set2 # {"apple", "orange", "bread"}
# Convert back to list if needed
to_buy_list = list(to_buy)Key Takeaways
Lists
- Ordered, mutable collections
- Use
[ ]brackets - Perfect for sequences that change
- Support indexing and slicing
Tuples
- Ordered, immutable collections
- Use
( )parentheses - Good for fixed data
- Can be dictionary keys
Dictionaries
- Key-value pairs
- Use
{ }braces - Fast lookups by key
- Keys must be immutable
Sets
- Unordered, unique elements
- Use
{ }braces - Great for duplicates removal
- Fast membership testing
What's Next?
Excellent! You now understand Python's core data structures. These are fundamental tools you'll use in almost every Python program. Next, we'll learn how to control the flow of your programs:
- Conditional statements - Make decisions with if/elif/else
- Loops - Iterate with for and while loops
- Loop control - Use break and continue statements
- Looping through structures - Iterate over lists, dictionaries, and sets