Python Basics - 03. Data Structures

To write efficient programs, you need ways to organize and store data. Python provides four fundamental built-in data structures: Lists, Tuples, Dictionaries, and Sets.

Download Notebook

Download this notebook

1. Lists (Ordered, Mutable array)

A list is a collection of ordered, mutable (changeable) elements. They are defined using square brackets [].

fruits = ["apple", "banana", "cherry"]
print(f"Initial list: {fruits}")

# Accessing elements (0-indexed)
print(f"Element at index 1: {fruits[1]}")

# Modifying an element (Mutable)
fruits[0] = "apricot"
print(f"After modification: {fruits}")

# Adding elements
fruits.append("orange")  # Adds to the end
print(f"After append: {fruits}")

# Removing an element by value
fruits.remove("banana")
print(f"After remove: {fruits}")
Initial list: ['apple', 'banana', 'cherry']
Element at index 1: banana
After modification: ['apricot', 'banana', 'cherry']
After append: ['apricot', 'banana', 'cherry', 'orange']
After remove: ['apricot', 'cherry', 'orange']

2. Tuples (Ordered, Immutable array)

A tuple works just like a list, but it is immutable (you cannot change its contents after creation). They are defined using parentheses ().

coords = (10, 20.5, 30.1)
print(f"Coordinates tuple: {coords}")
print(f"X Coordinate: {coords[0]}")

# Uncommenting the line below will result in an error!
# coords[0] = 15  # TypeError: 'tuple' object does not support item assignment
Coordinates tuple: (10, 20.5, 30.1)
X Coordinate: 10

3. Dictionaries (Key-Value mappings)

A dictionary is an unordered collection of data stored as key-value pairs. They allow fast lookups based on keys, and are defined using curly braces {}.

person = {
    "name": "Alice", 
    "age": 25, 
    "city": "New York"
}
print(f"Dictionary: {person}")

# Accessing a value by its key
print(f"Person's name: {person['name']}")

# Adding or updating a key-value pair
person["email"] = "[email protected]"  # Adding a new key
person["age"] = 26                   # Updating an existing key
print(f"Updated dictionary: {person}")

# Removing a key-value pair
del person["city"]
print(f"After deleting 'city': {person}")
Dictionary: {'name': 'Alice', 'age': 25, 'city': 'New York'}
Person's name: Alice
Updated dictionary: {'name': 'Alice', 'age': 26, 'city': 'New York', 'email': '[email protected]'}
After deleting 'city': {'name': 'Alice', 'age': 26, 'email': '[email protected]'}

4. Sets (Unordered, Unique elements)

A set is a collection of unordered elements where every item must be unique. They are very useful for mathematical set operations or deduplicating lists.

# Notice duplicate '3' and '4' are defined
numbers = {1, 2, 3, 3, 4, 4, 5}
print(f"Set (duplicates automatically removed): {numbers}")

numbers.add(6)
print(f"Added 6: {numbers}")

# Checking membership is very fast in a set
print(f"Is the number 3 inside the set? {3 in numbers}")
Set (duplicates automatically removed): {1, 2, 3, 4, 5}
Added 6: {1, 2, 3, 4, 5, 6}
Is the number 3 inside the set? True

5. Copying, Nested Structures, and Common Pitfalls

When data structures become nested, shallow vs deep copy matters:

  • copy() creates a shallow copy (outer container copied, inner objects shared).

  • deepcopy() recursively copies nested objects.

You should also know safe dictionary access with get() to avoid KeyError.

from copy import deepcopy

# Nested mutable data structure
original = {
    "user": "Alice",
    "skills": ["python", "sql"]
}

# Shallow copy: top-level dict is copied, but nested list is shared.
shallow = original.copy()

# Deep copy: full recursive copy, nested list is independent.
deep = deepcopy(original)

# Modifying nested list in shallow copy also affects original.
shallow["skills"].append("linux")
print("Original after shallow change:", original)
print("Shallow:", shallow)
print("Deep:", deep)

# Safe dictionary access with get()
# get("missing") returns None instead of raising KeyError.
data = {"name": "Bob"}
print(data.get("age"))            # None
print(data.get("age", "N/A"))     # Default fallback value
Original after shallow change: {'user': 'Alice', 'skills': ['python', 'sql', 'linux']}
Shallow: {'user': 'Alice', 'skills': ['python', 'sql', 'linux']}
Deep: {'user': 'Alice', 'skills': ['python', 'sql']}
None
N/A