Data Structures

Lists - Ordered Collections

Lists are ordered, mutable collections that can store different data types.

# Creating lists
fruits = ["apple", "banana", "orange"]
numbers = [1, 2, 3, 4, 5]
mixed = ["hello", 42, 3.14, True]
empty_list = []

# Accessing elements (indexing starts at 0)
print(fruits[0])     # apple
print(fruits[-1])    # orange (negative indexing from end)
print(fruits[1:3])   # ['banana', 'orange'] (slicing)

# Modifying lists
fruits[0] = "grape"  # Change first element
fruits.append("kiwi")        # Add to end
fruits.insert(1, "mango")    # Insert at position 1
fruits.remove("banana")      # Remove first occurrence
popped = fruits.pop()        # Remove and return last element

# List methods
print(len(fruits))           # Length of list
print("apple" in fruits)     # Check if item exists
fruits.sort()               # Sort in place
fruits.reverse()            # Reverse in place

Dictionaries - Key-Value Pairs

Dictionaries store data as key-value pairs, allowing fast lookups by key.

# Creating dictionaries
person = {
    "name": "Alice",
    "age": 30,
    "city": "New York"
}

# Alternative creation
student = dict(name="Bob", grade="A", subject="Math")

# Accessing values
print(person["name"])        # Alice
print(person.get("age"))     # 30
print(person.get("phone", "Not found"))  # Default value

# Modifying dictionaries
person["age"] = 31          # Update existing key
person["phone"] = "123-456" # Add new key-value pair
del person["city"]          # Delete key-value pair

# Dictionary methods
print(person.keys())        # Get all keys
print(person.values())      # Get all values
print(person.items())       # Get key-value pairs

# Looping through dictionaries
for key in person:
    print(f"{key}: {person[key]}")

for key, value in person.items():
    print(f"{key}: {value}")

Tuples - Immutable Sequences

Tuples are ordered, immutable collections. Once created, they cannot be changed.

# Creating tuples
coordinates = (10, 20)
colors = ("red", "green", "blue")
single_item = (42,)  # Note the comma for single item
empty_tuple = ()

# Accessing elements
print(coordinates[0])    # 10
print(colors[-1])        # blue
print(colors[1:3])       # ('green', 'blue')

# Tuple unpacking
x, y = coordinates
print(f"X: {x}, Y: {y}")

# Multiple assignment
name, age, city = ("Alice", 25, "Boston")

# Tuples are immutable
# coordinates[0] = 15  # This would cause an error!

# Tuple methods
print(len(colors))           # 3
print(colors.count("red"))   # 1
print(colors.index("green")) # 1

Sets - Unique Collections

Sets store unique elements and are useful for removing duplicates and set operations.

# Creating sets
fruits = {"apple", "banana", "orange"}
numbers = set([1, 2, 3, 2, 1])  # Duplicates removed: {1, 2, 3}
empty_set = set()  # Note: {} creates an empty dict, not set

# Adding and removing elements
fruits.add("grape")
fruits.remove("banana")     # Raises error if not found
fruits.discard("kiwi")      # No error if not found
popped = fruits.pop()       # Remove and return arbitrary element

# Set operations
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(set1.union(set2))        # {1, 2, 3, 4, 5, 6}
print(set1.intersection(set2)) # {3, 4}
print(set1.difference(set2))   # {1, 2}
print(set1.symmetric_difference(set2))  # {1, 2, 5, 6}

# Membership testing (very fast)
print(3 in set1)  # True

Comparison of Data Structures

StructureOrderedMutableDuplicatesUse Case
ListYesYesYesOrdered collection of items
DictionaryYes*YesNo (keys)Key-value mappings
TupleYesNoYesImmutable sequences
SetNoYesNoUnique elements, fast lookup

*Dictionaries maintain insertion order in Python 3.7+

List Comprehensions

A concise way to create lists based on existing sequences.

# Basic list comprehension
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares)  # [1, 4, 9, 16, 25]

# With condition
even_squares = [x**2 for x in numbers if x % 2 == 0]
print(even_squares)  # [4, 16]

# String manipulation
words = ["hello", "world", "python"]
uppercase = [word.upper() for word in words]
print(uppercase)  # ['HELLO', 'WORLD', 'PYTHON']

# Nested comprehension
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Working with Nested Structures

# List of dictionaries
students = [
    {"name": "Alice", "grade": 85, "subject": "Math"},
    {"name": "Bob", "grade": 92, "subject": "Science"},
    {"name": "Charlie", "grade": 78, "subject": "Math"}
]

# Accessing nested data
print(students[0]["name"])  # Alice

# Dictionary with lists
courses = {
    "Math": ["Alice", "Charlie", "David"],
    "Science": ["Bob", "Eve", "Frank"],
    "History": ["Alice", "Bob"]
}

# Adding to nested structure
courses["Math"].append("Grace")
courses["Art"] = ["Diana", "Henry"]

# Complex nested structure
school = {
    "name": "Python High School",
    "students": {
        "grade_9": ["Alice", "Bob"],
        "grade_10": ["Charlie", "Diana"]
    },
    "teachers": ["Mr. Smith", "Ms. Johnson"]
}
💡 Tip: Choose the right data structure for your needs:
← Control Flow Next: Functions →