intermediate
Step 9 of 20
Functions
Python Programming
Functions
Functions are reusable blocks of code that perform a specific task. They are one of the most important concepts in programming because they allow you to organize code into logical units, avoid repetition (DRY — Don't Repeat Yourself), and make your programs easier to read, test, and maintain. In Python, functions are first-class objects, meaning they can be assigned to variables, passed as arguments to other functions, and returned from functions.
Defining and Calling Functions
# Basic function definition
def greet():
print("Hello, World!")
greet() # Call the function
# Function with parameters
def greet_person(name):
print(f"Hello, {name}!")
greet_person("Alice") # "Hello, Alice!"
# Function with return value
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
# Returning multiple values (as a tuple)
def get_stats(numbers):
return min(numbers), max(numbers), sum(numbers) / len(numbers)
lo, hi, avg = get_stats([4, 8, 15, 16, 23, 42])
print(f"Min: {lo}, Max: {hi}, Avg: {avg:.1f}")
Parameters and Arguments
# Default parameters
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Alice") # "Hello, Alice!"
greet("Bob", "Hi") # "Hi, Bob!"
# Keyword arguments
def create_user(name, age, role="user"):
return {"name": name, "age": age, "role": role}
user = create_user(name="Alice", age=30, role="admin")
user2 = create_user("Bob", age=25) # Positional + keyword
# *args — variable positional arguments
def calculate_sum(*numbers):
total = 0
for num in numbers:
total += num
return total
print(calculate_sum(1, 2, 3)) # 6
print(calculate_sum(10, 20, 30, 40)) # 100
# **kwargs — variable keyword arguments
def build_profile(name, **details):
profile = {"name": name}
profile.update(details)
return profile
profile = build_profile("Alice", age=30, city="NYC", job="Developer")
print(profile)
# {'name': 'Alice', 'age': 30, 'city': 'NYC', 'job': 'Developer'}
# Combining all parameter types
def complex_func(a, b, *args, option=True, **kwargs):
print(f"a={a}, b={b}")
print(f"args={args}")
print(f"option={option}")
print(f"kwargs={kwargs}")
complex_func(1, 2, 3, 4, option=False, x=10, y=20)
Scope and Variable Visibility
# Local vs global scope
x = "global"
def my_func():
x = "local" # This is a different variable
print(x) # "local"
my_func()
print(x) # "global" (unchanged)
# Using global keyword (generally avoid this)
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
# Enclosing scope (closures)
def outer():
message = "Hello"
def inner():
print(message) # Accesses enclosing scope
inner()
outer() # "Hello"
# nonlocal keyword
def counter_factory():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = counter_factory()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3
Lambda Functions
# Lambda — anonymous one-line functions
square = lambda x: x ** 2
print(square(5)) # 25
add = lambda a, b: a + b
print(add(3, 4)) # 7
# Commonly used with sorted(), map(), filter()
students = [("Alice", 90), ("Bob", 78), ("Charlie", 95)]
sorted_by_score = sorted(students, key=lambda s: s[1], reverse=True)
print(sorted_by_score) # [('Charlie', 95), ('Alice', 90), ('Bob', 78)]
# map and filter
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squared = list(map(lambda x: x**2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(squared) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
print(evens) # [2, 4, 6, 8, 10]
Type Hints and Docstrings
def calculate_bmi(weight_kg: float, height_m: float) -> float:
"""Calculate Body Mass Index (BMI).
Args:
weight_kg: Weight in kilograms.
height_m: Height in meters.
Returns:
The BMI value as a float.
Raises:
ValueError: If height is zero or negative.
"""
if height_m <= 0:
raise ValueError("Height must be positive")
return weight_kg / (height_m ** 2)
bmi = calculate_bmi(70, 1.75)
print(f"BMI: {bmi:.1f}") # BMI: 22.9
Pro tip: Follow the single-responsibility principle: each function should do one thing and do it well. If a function is getting too long (more than 20-30 lines) or doing multiple unrelated things, break it into smaller functions.
Key Takeaways
- Functions are defined with
def, can accept parameters, and return values withreturn. - Python supports default parameters, keyword arguments,
*args(variable positional), and**kwargs(variable keyword). - Variables inside functions have local scope; use
globalandnonlocalsparingly to modify outer variables. - Lambda functions provide concise anonymous functions for simple operations, commonly used with
sorted(),map(), andfilter(). - Always write docstrings and consider type hints for better code documentation and IDE support.