Builder to Architect
Python

Functions & Lists in Python

Learn to organize code with functions and work with lists — Python's most versatile data structure.

Functions — Reusable Code Blocks

Last week you wrote code that runs top to bottom. But what if you need the same logic in multiple places? That's where functions come in.

A function is a named block of code that you can call whenever you need it:

def calculate_margin(revenue, cost):
    margin = (revenue - cost) / revenue * 100
    return round(margin, 1)

# Now use it
print(calculate_margin(100000, 70000))  # → 30.0
print(calculate_margin(50000, 40000))   # → 20.0
  • def defines a function
  • calculate_margin is the name
  • revenue, cost are parameters (inputs)
  • return sends a value back to whoever called the function

You've already used built-in functions: print(), type(), len(). Now you can create your own.

Why Functions Matter

Functions aren't just convenient — they're how you think like an architect:

  1. Reusability: Write once, use everywhere
  2. Abstraction: Hide complex details behind a simple name
  3. Testing: You can test each function independently
  4. Readability: calculate_margin(revenue, cost) is clearer than the math formula inline

In your vibe-coding projects, you already use functions (React components are functions!). Now understand why they're structured this way.

Parameters and Return Values

# Function with no parameters
def greet():
    print("Hello!")

# Function with default parameter
def greet_client(name="Client"):
    print(f"Hello, {name}!")

greet_client()           # → Hello, Client!
greet_client("Teliani")  # → Hello, Teliani!

# Function with multiple return values
def analyze_deal(amount, cost):
    profit = amount - cost
    margin = profit / amount * 100
    return profit, margin

p, m = analyze_deal(50000, 35000)
print(f"Profit: ${p}, Margin: {m:.1f}%")  # → Profit: $15000, Margin: 30.0%

Scope — Where Variables Live

Variables created inside a function only exist inside that function:

def set_price():
    price = 100     # This 'price' only exists inside set_price
    return price

# print(price)      # ERROR! 'price' doesn't exist out here
result = set_price()
print(result)        # → 100 (this works)

This is called scope. It prevents functions from accidentally interfering with each other. Each function has its own "workspace."

Lists — Ordered Collections

A list is an ordered collection of items. Think of it as a dynamic spreadsheet column:

countries = ["France", "Belgium", "Turkey", "Qatar"]
prices = [19.99, 24.50, 15.00, 32.99]
mixed = ["Lia", 29, True, 3.14]    # Lists can hold different types

Accessing Items

Lists use zero-based indexing (first item is index 0):

countries = ["France", "Belgium", "Turkey", "Qatar"]

countries[0]     # → "France"
countries[1]     # → "Belgium"
countries[-1]    # → "Qatar" (last item)
countries[-2]    # → "Turkey" (second to last)

Slicing

Get a portion of a list:

countries[1:3]   # → ["Belgium", "Turkey"] (index 1 up to but not including 3)
countries[:2]    # → ["France", "Belgium"] (first 2)
countries[2:]    # → ["Turkey", "Qatar"] (from index 2 to end)

Modifying Lists

countries = ["France", "Belgium"]

countries.append("Turkey")       # Add to end → ["France", "Belgium", "Turkey"]
countries.insert(1, "Spain")     # Insert at index 1 → ["France", "Spain", "Belgium", "Turkey"]
countries.remove("Belgium")      # Remove by value → ["France", "Spain", "Turkey"]
del countries[0]                 # Remove by index → ["Spain", "Turkey"]

Useful List Operations

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

len(numbers)           # → 8 (length)
sorted(numbers)        # → [1, 1, 2, 3, 4, 5, 6, 9] (returns new sorted list)
numbers.sort()         # Sorts in place (modifies original)
sum(numbers)           # → 31
min(numbers)           # → 1
max(numbers)           # → 9

"France" in countries  # → True/False (check membership)

Looping Through Lists

countries = ["France", "Belgium", "Turkey"]

# Simple loop
for country in countries:
    print(f"Shipping to {country}")

# Loop with index
for i, country in enumerate(countries):
    print(f"{i + 1}. {country}")
# 1. France
# 2. Belgium
# 3. Turkey

List Comprehensions (Powerful Shortcut)

# Traditional way
upper_countries = []
for c in countries:
    upper_countries.append(c.upper())

# List comprehension (same result, one line)
upper_countries = [c.upper() for c in countries]
# → ["FRANCE", "BELGIUM", "TURKEY"]

# With a filter
eu_countries = [c for c in countries if c != "Turkey"]
# → ["France", "Belgium"]

List comprehensions are one of Python's most powerful features. They're everywhere in professional Python code.

Connecting to What You Know

In your Next.js projects, you use JavaScript arrays all the time:

const items = posts.map(p => p.title)   // JavaScript
items = [p.title for p in posts]        # Python equivalent

Same concept, slightly different syntax.

What to Do This Week

  1. Read Chapters 3 and 4 of Automate the Boring Stuff
  2. Practice: Write a function called export_report that takes a list of countries and a list of deal values, and prints a formatted report
  3. Experiment with lists: Create a list of your GEC client names, sort them, filter them, loop through them
  4. Take the quiz below.

Quiz

Question 1/5Score: 0

What does the `return` keyword do in a function?