Functions Advanced
Learn advanced function concepts like args, kwargs, and lambda
What You'll Learn
- Unlimited parameters (*args)
- Keyword parameters (**kwargs)
- Lambda functions (one-liners)
- Docstrings (function documentation)
Unlimited Parameters (*args)
Accept any number of arguments:
def add_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(add_all(1, 2, 3)) # 6
print(add_all(1, 2, 3, 4, 5)) # 15The * collects all arguments into a tuple.
Example: Average
def calculate_average(*numbers):
if len(numbers) == 0:
return 0
return sum(numbers) / len(numbers)
print(calculate_average(10, 20, 30)) # 20.0
print(calculate_average(5, 10, 15, 20)) # 12.5Keyword Parameters (**kwargs)
Accept any number of named arguments:
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="John", age=25, city="New York")Output:
name: John
age: 25
city: New York
Example: Build profile
def create_profile(**details):
profile = {}
for key, value in details.items():
profile[key] = value
return profile
user = create_profile(name="Sarah", age=28, job="Developer")
print(user)
# {'name': 'Sarah', 'age': 28, 'job': 'Developer'}Combining Parameters
Order matters:
- Regular parameters
- *args
- **kwargs
def make_pizza(size, *toppings, **details):
print(f"Size: {size}")
print("Toppings:")
for topping in toppings:
print(f"- {topping}")
print("Details:")
for key, value in details.items():
print(f"{key}: {value}")
make_pizza("Large", "cheese", "pepperoni", crust="thick", delivery=True)Lambda Functions
Short, one-line functions:
Normal function:
def double(x):
return x * 2
print(double(5)) # 10Lambda version:
double = lambda x: x * 2
print(double(5)) # 10Format:
lambda parameters: expressionMultiple parameters:
add = lambda a, b: a + b
print(add(3, 5)) # 8
multiply = lambda a, b: a * b
print(multiply(4, 6)) # 24Lambda with Built-in Functions
Sort by custom key:
students = [
{"name": "John", "age": 25},
{"name": "Sarah", "age": 22},
{"name": "Mike", "age": 28}
]
# Sort by age
sorted_students = sorted(students, key=lambda s: s["age"])
for student in sorted_students:
print(f"{student['name']}: {student['age']}")Filter list:
numbers = [1, 5, 8, 12, 3, 15]
# Get numbers > 5
big_numbers = list(filter(lambda x: x > 5, numbers))
print(big_numbers) # [8, 12, 15]Map (transform each item):
numbers = [1, 2, 3, 4, 5]
# Double each number
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8, 10]Docstrings (Function Documentation)
Explain what your function does:
def calculate_bmi(weight, height):
"""
Calculate Body Mass Index.
Parameters:
weight (float): Weight in kilograms
height (float): Height in meters
Returns:
float: BMI value
"""
return weight / (height ** 2)
# Access docstring
print(calculate_bmi.__doc__)Simple docstring:
def greet(name):
"""Say hello to a person."""
print(f"Hello {name}!")Practice Examples
Example 1: Flexible greeting
def greet_all(*names):
for name in names:
print(f"Hello {name}!")
greet_all("John", "Sarah", "Mike")Example 2: Build URL
def build_url(base, **params):
url = base + "?"
param_list = []
for key, value in params.items():
param_list.append(f"{key}={value}")
url += "&".join(param_list)
return url
url = build_url("api.com", user="john", page=1, limit=10)
print(url)
# api.com?user=john&page=1&limit=10Example 3: Calculate stats
def get_stats(*numbers):
"""Calculate min, max, and average."""
if not numbers:
return None
return {
"min": min(numbers),
"max": max(numbers),
"avg": sum(numbers) / len(numbers)
}
stats = get_stats(10, 20, 30, 40, 50)
print(stats)
# {'min': 10, 'max': 50, 'avg': 30.0}Real-World Examples
Example 1: Logging function
def log_message(level, *messages, **details):
print(f"[{level}]", " ".join(messages))
if details:
print("Details:", details)
log_message("ERROR", "Failed", "to", "connect", code=500, retry=True)Example 2: Price calculator
def calculate_total(*prices, tax=0.08, discount=0):
subtotal = sum(prices)
tax_amount = subtotal * tax
discount_amount = subtotal * discount
total = subtotal + tax_amount - discount_amount
return total
# Regular purchase
print(calculate_total(10, 20, 30)) # 64.8
# With discount
print(calculate_total(10, 20, 30, discount=0.1)) # 58.32When to Use Each
Regular functions:
- Most common use
- When you know exact parameters
Lambda:
- Quick, simple operations
- Used with map, filter, sorted
- Don't use for complex logic
*args:
- Unknown number of arguments
- Making flexible functions
**kwargs:
- Optional named parameters
- Configuration settings
Common Mistakes
Mistake 1: Wrong order
# Wrong
def func(**kwargs, *args): # Error!
# Correct
def func(*args, **kwargs):Mistake 2: Complex lambda
# Too complex for lambda
calc = lambda x: x * 2 if x > 0 else x / 2 if x < 0 else 0
# Better as regular function
def calc(x):
if x > 0:
return x * 2
elif x < 0:
return x / 2
else:
return 0Quick Reference
*args (unlimited arguments):
def func(*args):
# args is a tuple**kwargs (keyword arguments):
def func(**kwargs):
# kwargs is a dictionaryLambda:
lambda params: expressionDocstring:
def func():
"""Description here"""Summary
- *args for unlimited arguments
- **kwargs for keyword arguments
- Lambda for short, simple functions
- Docstrings document your code
- Order: regular, *args, **kwargs
- Use what makes code clearest
What's Next?
Now let's understand variable scope and how Python finds variables!