All Courses
Python Basics

Python Functions

1. What is a Function?

A function is a reusable block of code that can be called multiple times. Built-in examples include len(), int(), print(), and input().


2. Defining a Function

def function_name(parameters):
    # function body
  • Use the def keyword
  • Name rules: no spaces, no special characters (except _), can't start with a number
  • Use snake_case for multi-word names (e.g. print_value)
  • The function body is indented

No parameters

def print_hello():
    print("hello")

With parameters

def print_value(value):
    print(value)

3. Calling a Function

print_hello()              # no arguments
print_value("hi")          # one argument
print_value(1)             # different argument

Parameters = variable names defined in the function signature. Arguments = actual values passed when calling the function.


4. Return Values

Use return to send a value back to where the function was called.

def add_five(x, y, z):
    result = x + y + z
    return result

r = add_five(4, 5, 6)
print(r)   # → 15
  • Without return, the function returns None by default
  • As soon as return is hit, the function stops immediately — nothing after it runs
  • You can have multiple return statements (only the first one reached will execute)
def get_negative_sum(x, y, z):
    result = x + y + z
    if result < 0:
        return result
    return 1    # no else needed — if above return ran, we never get here

5. Returning Multiple Values

Separate return values with a comma — they come back as a tuple.

def return_values(x, y):
    return x + 1, y + 1

result = return_values(1, 2)    # → (2, 3)

# Unpack directly into variables
x, y = return_values(1, 2)      # x = 2, y = 3

6. Default / Optional Parameters

Give a parameter a default value so it doesn't have to be passed.

def new_range(start=0, stop=10):
    x = start
    while x < stop:
        print(x)
        x += 1

new_range()          # uses defaults: 0 to 9
new_range(5)         # start=5, stop=10 (default)
new_range(5, 15)     # start=5, stop=15

⚠️ Rule: Parameters with default values must come after parameters without default values.

def example(stop, start=0):   # ✅ valid
def example(start=0, stop):   # ❌ SyntaxError

7. Keyword Arguments

Pass arguments by name instead of position — useful for skipping optional parameters.

def new_range(start=0, stop=10):
    ...

new_range(stop=5)               # start uses default, stop=5
new_range(stop=15, start=2)     # order doesn't matter with keywords
Argument style Example
Positional new_range(2, 15)
Keyword new_range(stop=15, start=2)

You can't pass the same argument both positionally and by keyword: new_range(2, start=5)TypeError: got multiple values for argument 'start'


8. Functions Calling Other Functions

Functions can call other functions — a common pattern to avoid repeating code.

def sum_of_list(lst):
    total = 0
    for num in lst:
        total += num
    return total

def sum_lists(list1, list2):
    list1_sum = sum_of_list(list1)
    list2_sum = sum_of_list(list2)
    return list1_sum, list2_sum

s1, s2 = sum_lists([1, 2, 3, 4], [-1, -2, -3, -4])
print(s1, s2)   # → 10 -10

9. Function Definition Order

Functions must be defined before they are called at the top (main) level.

# ❌ Wrong — calling before defining
result = add(1, 2)

def add(x, y):
    return x + y
# ✅ Correct — define first, call after
def add(x, y):
    return x + y

result = add(1, 2)

Best practice: Put all function definitions at the top of your file, and your main code at the bottom.


10. Nested Functions

You can define a function inside another function. It's only accessible within that outer function.

def sum_lists(list1, list2):
    def sum_of_list(lst):       # only available inside sum_lists
        total = 0
        for num in lst:
            total += num
        return total

    return sum_of_list(list1), sum_of_list(list2)

11. Practical Example — Remove Characters

def remove_chars(base, chars=""):
    new_string = base
    for char in chars:
        new_string = new_string.replace(char, "")
    return new_string

result = remove_chars("hello world", "l")
print(result)   # → "heo word"

result = remove_chars("hello world")   # chars defaults to ""
print(result)   # → "hello world"

Cheat Sheet

# Define
def my_func(param1, param2="default"):
    return param1 + param2

# Call — positional
my_func("a", "b")

# Call — keyword
my_func(param2="b", param1="a")

# Return multiple values
def multi():
    return 1, 2        # returns tuple (1, 2)

x, y = multi()         # unpack

# No return → returns None
def no_return():
    print("hi")

result = no_return()   # result is None

Key Terms

Term Definition
Parameter Variable name in the function definition
Argument Actual value passed when calling the function
Default parameter Parameter with a preset value; becomes optional
Positional argument Passed by order/position
Keyword argument Passed by name (param=value)
Return value Value sent back by return
Nested function A function defined inside another function