Daily Tech Brief

Top startup stories in your inbox

Subscribe Free

© 2026 rakrisi Daily

Lists and Tuples - Sequential Data

Lists and Tuples: Sequential Data Structures

Welcome to the foundation of Python data structures! Lists and tuples are like the bread and butter of data organization - they keep things in order.

Lists: Mutable Ordered Collections

Creating Lists

# Empty list
empty_list = []

# List with initial values
numbers = [1, 2, 3, 4, 5]
fruits = ["apple", "banana", "orange"]
mixed = [1, "hello", True, 3.14, [1, 2, 3]]

# Using list() constructor
from_range = list(range(5))  # [0, 1, 2, 3, 4]
from_string = list("hello")  # ['h', 'e', 'l', 'l', 'o']

Accessing List Elements

fruits = ["apple", "banana", "orange", "grape", "kiwi"]

# Positive indexing (from start)
print(fruits[0])   # "apple"
print(fruits[2])   # "orange"

# Negative indexing (from end)
print(fruits[-1])  # "kiwi"
print(fruits[-2])  # "grape"

# Getting list length
print(len(fruits))  # 5

Modifying Lists

fruits = ["apple", "banana", "orange"]

# Change element
fruits[1] = "blueberry"
print(fruits)  # ["apple", "blueberry", "orange"]

# Add elements
fruits.append("grape")        # Add to end
print(fruits)  # ["apple", "blueberry", "orange", "grape"]

fruits.insert(1, "avocado")   # Insert at position 1
print(fruits)  # ["apple", "avocado", "blueberry", "orange", "grape"]

# Remove elements
fruits.remove("orange")       # Remove by value
print(fruits)  # ["apple", "avocado", "blueberry", "grape"]

popped = fruits.pop()         # Remove and return last element
print(f"Popped: {popped}")    # "grape"
print(fruits)  # ["apple", "avocado", "blueberry"]

popped_index = fruits.pop(1)  # Remove and return element at index 1
print(f"Popped at index 1: {popped_index}")  # "avocado"

List Slicing

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Basic slicing [start:end] (end not included)
print(numbers[2:5])   # [2, 3, 4]
print(numbers[:3])    # [0, 1, 2] (from start to index 3)
print(numbers[7:])    # [7, 8, 9] (from index 7 to end)

# With step [start:end:step]
print(numbers[::2])   # [0, 2, 4, 6, 8] (every 2nd element)
print(numbers[1::2])  # [1, 3, 5, 7, 9] (every 2nd starting from index 1)
print(numbers[::-1])  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (reverse)

# Replace multiple elements with slice
numbers[2:5] = [20, 30, 40]
print(numbers)  # [0, 1, 20, 30, 40, 5, 6, 7, 8, 9]

# Delete multiple elements
numbers[2:5] = []
print(numbers)  # [0, 1, 5, 6, 7, 8, 9]

List Methods

fruits = ["apple", "banana", "orange", "apple", "grape"]

# Count occurrences
print(fruits.count("apple"))  # 2

# Find index of first occurrence
print(fruits.index("banana"))  # 1

# Sort in place
fruits.sort()
print(fruits)  # ['apple', 'apple', 'banana', 'grape', 'orange']

# Reverse in place
fruits.reverse()
print(fruits)  # ['orange', 'grape', 'banana', 'apple', 'apple']

# Create sorted copy (doesn't modify original)
original = ["c", "a", "b"]
sorted_copy = sorted(original)
print("Original:", original)     # ['c', 'a', 'b']
print("Sorted copy:", sorted_copy)  # ['a', 'b', 'c']

# Extend list with another list
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2)
print(list1)  # [1, 2, 3, 4, 5, 6]

# Clear all elements
list1.clear()
print(list1)  # []

Tuples: Immutable Ordered Collections

Creating Tuples

# Empty tuple
empty_tuple = ()

# Single element tuple (note the comma!)
single = (42,)
single_alternative = 42,  # Also works

# Multiple elements
coordinates = (10, 20, 30)
person = ("Alice", 25, "Engineer")
colors = "red", "green", "blue"  # Parentheses optional

print(type(colors))  # <class 'tuple'>

Tuple Operations

point = (10, 20, 30)

# Access elements (same as lists)
print(point[0])   # 10
print(point[-1])  # 30

# Slicing (same as lists)
print(point[1:])  # (20, 30)

# Length
print(len(point))  # 3

# Count and index methods
numbers = (1, 2, 3, 2, 1)
print(numbers.count(2))  # 2
print(numbers.index(3))  # 2

# Tuples are immutable - cannot modify!
# point[0] = 15  # TypeError: 'tuple' object does not support item assignment

Tuple Unpacking

# Basic unpacking
point = (10, 20)
x, y = point
print(f"x: {x}, y: {y}")  # x: 10, y: 20

# Extended unpacking
numbers = (1, 2, 3, 4, 5)
first, *middle, last = numbers
print(f"First: {first}")    # 1
print(f"Middle: {middle}")  # [2, 3, 4]
print(f"Last: {last}")      # 5

# Unpacking in function returns
def get_user_info():
    return "Alice", 25, "alice@email.com"

name, age, email = get_user_info()
print(f"Name: {name}, Age: {age}, Email: {email}")

When to Use Lists vs Tuples

Use Lists When:

# 1. You need to modify the collection
shopping_list = ["milk", "bread", "eggs"]
shopping_list.append("butter")  # Can add items
shopping_list[0] = "almond milk"  # Can modify items

# 2. The collection will change size
user_posts = []  # Start empty
user_posts.append("First post")
user_posts.append("Second post")

# 3. You need to sort or reverse
scores = [85, 92, 78, 96]
scores.sort()  # [78, 85, 92, 96]
scores.reverse()  # [96, 92, 85, 78]

Use Tuples When:

# 1. Data should not change (immutable)
# GPS coordinates
locations = [
    (40.7128, -74.0060),  # NYC
    (34.0522, -118.2437)  # LA
]

# 2. Function returns multiple values
def divide_with_remainder(a, b):
    quotient = a // b
    remainder = a % b
    return quotient, remainder

result, remainder = divide_with_remainder(17, 5)
print(f"17 ÷ 5 = {result} remainder {remainder}")

# 3. Dictionary keys (lists cannot be keys)
student_grades = {
    ("Alice", "Smith"): "A",
    ("Bob", "Jones"): "B"
}

# 4. Unpacking assignments
name, age, city = ("Alice", 25, "New York")

List and Tuple Comprehensions

List Comprehensions

# 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]

# Nested comprehensions
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]

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

Tuple Comprehensions (Generator Expressions)

# Tuple comprehensions create generators
numbers = [1, 2, 3, 4, 5]
squares_gen = (x**2 for x in numbers)
print(type(squares_gen))  # <class 'generator'>

# Convert to tuple
squares_tuple = tuple(squares_gen)
print(squares_tuple)  # (1, 4, 9, 16, 25)

# Or iterate directly
for square in (x**2 for x in numbers):
    print(square, end=" ")  # 1 4 9 16 25
print()

Real-World Examples

Example 1: Task Manager

def add_task(tasks, task):
    """Add a task to the list."""
    tasks.append(task)
    print(f"Added task: {task}")

def complete_task(tasks, index):
    """Mark a task as completed and remove it."""
    if 0 <= index < len(tasks):
        completed = tasks.pop(index)
        print(f"Completed: {completed}")
    else:
        print("Invalid task index")

def show_tasks(tasks):
    """Display all tasks with indices."""
    if not tasks:
        print("No tasks remaining!")
    else:
        print("Current tasks:")
        for i, task in enumerate(tasks):
            print(f"{i}. {task}")

# Usage
tasks = []
add_task(tasks, "Buy groceries")
add_task(tasks, "Finish homework")
add_task(tasks, "Call mom")

show_tasks(tasks)
complete_task(tasks, 1)  # Complete "Finish homework"
show_tasks(tasks)

Example 2: Student Grade Analyzer

def calculate_average(grades):
    """Calculate average of grades."""
    if not grades:
        return 0
    return sum(grades) / len(grades)

def find_highest(grades):
    """Find the highest grade."""
    if not grades:
        return None
    return max(grades)

def get_grade_distribution(grades):
    """Categorize grades into letter grades."""
    distribution = {"A": 0, "B": 0, "C": 0, "D": 0, "F": 0}

    for grade in grades:
        if grade >= 90:
            distribution["A"] += 1
        elif grade >= 80:
            distribution["B"] += 1
        elif grade >= 70:
            distribution["C"] += 1
        elif grade >= 60:
            distribution["D"] += 1
        else:
            distribution["F"] += 1

    return distribution

# Student data as list of tuples
students = [
    ("Alice", [85, 92, 88, 95]),
    ("Bob", [78, 85, 90, 82]),
    ("Charlie", [92, 96, 89, 94])
]

for name, grades in students:
    avg = calculate_average(grades)
    highest = find_highest(grades)
    print(f"{name}: Average={avg:.1f}, Highest={highest}")

# Overall grade distribution
all_grades = [grade for _, grades in students for grade in grades]
distribution = get_grade_distribution(all_grades)
print(f"Grade distribution: {distribution}")

Example 3: Simple Database (Tuple of Lists)

# Simple in-memory database using tuples
def create_database():
    """Create a simple database structure."""
    # Return tuple of (users, products, orders)
    users = []      # List of (user_id, name, email) tuples
    products = []   # List of (product_id, name, price) tuples
    orders = []     # List of (order_id, user_id, product_id, quantity) tuples
    return users, products, orders

def add_user(db, user_id, name, email):
    """Add a user to the database."""
    users, _, _ = db
    users.append((user_id, name, email))
    print(f"Added user: {name}")

def add_product(db, product_id, name, price):
    """Add a product to the database."""
    _, products, _ = db
    products.append((product_id, name, price))
    print(f"Added product: {name} (${price})")

def place_order(db, order_id, user_id, product_id, quantity):
    """Place an order."""
    _, _, orders = db
    orders.append((order_id, user_id, product_id, quantity))
    print(f"Order placed: {quantity} x product {product_id} for user {user_id}")

def get_user_orders(db, user_id):
    """Get all orders for a user."""
    _, _, orders = db
    user_orders = [order for order in orders if order[1] == user_id]
    return user_orders

# Usage
db = create_database()

add_user(db, 1, "Alice", "alice@email.com")
add_user(db, 2, "Bob", "bob@email.com")

add_product(db, 101, "Laptop", 999)
add_product(db, 102, "Mouse", 25)

place_order(db, 1001, 1, 101, 1)  # Alice buys 1 laptop
place_order(db, 1002, 1, 102, 2)  # Alice buys 2 mice
place_order(db, 1003, 2, 102, 1)  # Bob buys 1 mouse

alice_orders = get_user_orders(db, 1)
print(f"Alice's orders: {alice_orders}")

Common Mistakes

1. Mutable Default Arguments

# ❌ Wrong - mutable default argument
def add_item(item, shopping_list=[]):
    shopping_list.append(item)
    return shopping_list

list1 = add_item("milk")
list2 = add_item("bread")
print(list1)  # ['milk', 'bread'] - unexpected!
print(list2)  # ['milk', 'bread'] - same list!

# ✅ Correct - use None as default
def add_item(item, shopping_list=None):
    if shopping_list is None:
        shopping_list = []
    shopping_list.append(item)
    return shopping_list

list1 = add_item("milk")
list2 = add_item("bread")
print(list1)  # ['milk']
print(list2)  # ['bread']

2. Modifying List While Iterating

# ❌ Dangerous - modifying list while iterating
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)

print(numbers)  # [1, 3, 5] - but missing some evens?

# ✅ Safe - create new list or iterate backwards
numbers = [1, 2, 3, 4, 5]
evens = [num for num in numbers if num % 2 != 0]
print(evens)  # [1, 3, 5]

3. Forgetting Tuple Comma

# ❌ Not a tuple
not_tuple = (42)
print(type(not_tuple))  # <class 'int'>

# ✅ Tuple with one element
single_tuple = (42,)
print(type(single_tuple))  # <class 'tuple'>

Performance Tips

List Operations Performance

# Fast operations (O(1))
my_list = [1, 2, 3]
my_list.append(4)     # Fast - add to end
my_list.pop()         # Fast - remove from end
len(my_list)          # Fast - get length

# Slow operations (O(n))
my_list.insert(0, 0)  # Slow - shift all elements
my_list.remove(2)     # Slow - search and shift
2 in my_list          # Slow - linear search

Choosing the Right Structure

# For fixed data that won't change
MONTHS = ("January", "February", "March", "April", "May", "June",
          "July", "August", "September", "October", "November", "December")

# For data that needs modification
user_posts = []  # Start empty, will grow

# For coordinates (natural tuples)
coordinates = [(40.7128, -74.0060), (34.0522, -118.2437)]

# For lookup tables (use dict, not list of tuples)
country_codes = {"US": "United States", "CA": "Canada", "UK": "United Kingdom"}

Practice Exercises

Exercise 1: To-Do List

Create a to-do list application with:

  • Add task
  • Remove task by index
  • Mark task as complete
  • Show all tasks
  • Clear all tasks

Exercise 2: Grade Calculator

Build a grade calculator that:

  • Stores grades in a list
  • Calculates average
  • Finds highest/lowest grade
  • Shows grade distribution (A, B, C, D, F)

Exercise 3: Shopping Cart

Create a shopping cart system:

  • Add items (name, price, quantity)
  • Remove items
  • Calculate total price
  • Apply discount
  • Show cart contents

Exercise 4: Text Analyzer

Build a text analyzer that:

  • Splits text into words
  • Counts word frequencies
  • Finds longest/shortest words
  • Removes duplicates
  • Sorts words alphabetically

Exercise 5: Matrix Operations

Create matrix operations:

  • Create identity matrix
  • Transpose matrix
  • Add two matrices
  • Multiply matrix by scalar
  • Print matrix nicely

Summary

Lists and tuples are fundamental data structures:

Lists (mutable, ordered):

  • Create: [] or list()
  • Modify: append(), insert(), remove(), pop()
  • Access: list[index], slicing [start:end:step]
  • Use for: collections that change

Tuples (immutable, ordered):

  • Create: () or comma-separated values
  • Access: same as lists
  • Unpack: a, b, c = tuple
  • Use for: fixed data, multiple returns, dictionary keys

Comprehensions:

  • Lists: [expression for item in iterable if condition]
  • Generators: (expression for item in iterable if condition)

Choose based on your needs:

  • Lists for dynamic collections
  • Tuples for fixed, immutable data
  • Comprehensions for concise transformations

Next: Dictionaries and Sets - key-value and unique data! 🔑