Back to blog
← View series: python tutorials

~/blog

Functions - Advanced

Apr 1, 20265 min readBy Mohammed Vasim
PythonProgrammingTutorialBeginner

Introduction

In this tutorial, you'll learn advanced function concepts in Python: lambda functions, *args and **kwargs, decorators, and more. These techniques will help you write more powerful and flexible code.

What You'll Learn

  • Lambda functions (anonymous functions)
  • *args and **kwargs
  • Decorators
  • Function composition
  • Map, filter, and reduce

Lambda Functions

Lambda functions are small, anonymous functions defined in a single line. They're useful when you need a simple function for a short period.

Basic Lambda

python
# Regular function
def square(x):
    return x ** 2

# Lambda equivalent
square = lambda x: x ** 2

print(square(5))    # 25

Lambda Syntax

python
# lambda parameters: expression

Lambda with Multiple Parameters

python
# Addition
add = lambda a, b: a + b
print(add(3, 5))    # 8

# Full name
full_name = lambda first, last: f"{first} {last}"
print(full_name("John", "Doe"))   # John Doe

When to Use Lambda

Lambda functions are commonly used with built-in functions like map(), filter(), and sorted():

python
# With map() - apply function to each item
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)      # [1, 4, 9, 16, 25]

# With sort() - using a key function
names = ["Alice", "Bob", "Charlie", "David"]
# Sort by length
sorted_names = sorted(names, key=lambda x: len(x))
print(sorted_names)    # ['Bob', 'Alice', 'David', 'Charlie']

*args and **kwargs

These special parameters allow functions to accept variable numbers of arguments.

*args - Variable Positional Arguments

python
def sum_all(*args):
    print(f"args type: {type(args)}")
    return sum(args)

print(sum_all(1, 2, 3))           # 6
print(sum_all(1, 2, 3, 4, 5))     # 15
print(sum_all())                  # 0

**kwargs - Variable Keyword Arguments

python
def print_info(**kwargs):
    print(f"kwargs type: {type(kwargs)}")
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25)
# name: Alice
# age: 25

Combining All

python
def flexible_function(required, *args, **kwargs):
    print(f"Required: {required}")
    print(f"Args: {args}")
    print(f"Kwargs: {kwargs}")

flexible_function("hello", 1, 2, 3, name="Alice", age=25)

Output:

Required: hello Args: (1, 2, 3) _kwargs: {'name': 'Alice', 'age': 25}

Practical Example

python
def calculate_stats(operation, *numbers):
    if operation == "sum":
        return sum(numbers)
    elif operation == "average":
        return sum(numbers) / len(numbers) if numbers else 0
    elif operation == "max":
        return max(numbers) if numbers else None
    elif operation == "min":
        return min(numbers) if numbers else None

print(calculate_stats("sum", 1, 2, 3, 4, 5))        # 15
print(calculate_stats("average", 10, 20, 30))      # 20.0
print(calculate_stats("max", 3, 1, 4, 1, 5))       # 5

Decorators

Decorators are functions that modify the behavior of other functions. They're a powerful way to add functionality without modifying the original function.

Basic Decorator

python
def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

Output:

Before function call Hello! After function call

Decorator with Arguments

python
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Output:

Hello, Alice! Hello, Alice! Hello, Alice!

Practical Decorator Example

python
import time

def timer(func):
    """Decorator to measure execution time"""
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.4f} seconds")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    print("Function completed!")

slow_function()

Multiple Decorators

python
def decorator1(func):
    def wrapper():
        print("Decorator 1 - Before")
        func()
        print("Decorator 1 - After")
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2 - Before")
        func()
        print("Decorator 2 - After")
    return wrapper

@decorator1
@decorator2
def say_hello():
    print("Hello!")

say_hello()

Output:

Decorator 1 - Before Decorator 2 - Before Hello! Decorator 2 - After Decorator 1 - After

Map, Filter, and Reduce

These are functional programming tools for processing collections.

map() - Apply Function to All Items

python
# Square all numbers
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# Convert to uppercase
words = ["hello", "world"]
upper = list(map(str.upper, words))
print(upper)    # ['HELLO', 'WORLD']

filter() - Keep Items Meeting Condition

python
# Keep even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)    # [2, 4, 6, 8, 10]

# Keep words with length > 4
words = ["cat", "elephant", "dog", "hippopotamus"]
long_words = list(filter(lambda x: len(x) > 4, words))
print(long_words)  # ['elephant', 'hippopotamus']

reduce() - Accumulate Values

python
from functools import reduce

# Sum all numbers
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
print(total)   # 15

# Find maximum
maximum = reduce(lambda x, y: x if x > y else y, numbers)
print(maximum) # 5

# Multiply all numbers
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120

Function Composition

Combining simple functions to build complex operations:

python
def compose(f, g):
    """Compose two functions: f(g(x))"""
    return lambda x: f(g(x))

# Example
add_one = lambda x: x + 1
double = lambda x: x * 2

# Create composed function
add_one_then_double = compose(double, add_one)
print(add_one_then_double(5))  # 12 ( (5+1) * 2 )

Summary

In this tutorial, you learned:

  • ✅ Lambda functions (anonymous functions)
  • ✅ *args for variable positional arguments
  • ✅ **kwargs for variable keyword arguments
  • ✅ Decorators and how to create them
  • ✅ Map, filter, and reduce functions
  • ✅ Function composition

🧑‍💻 Practice Exercise

Create a program that:

  1. Has a decorator that logs function calls (prints "Calling [function name]")
  2. Has a function that accepts *args and calculates sum and product
  3. Uses lambda with map/filter to process a list of numbers
Click to see solution
python
# Decorator to log function calls
def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} returned {result}")
        return result
    return wrapper

@logger
def calculate_sum(*numbers):
    """Calculate sum of all numbers"""
    return sum(numbers)

@logger
def calculate_product(*numbers):
    """Calculate product of all numbers"""
    result = 1
    for num in numbers:
        result *= num
    return result

# Test the functions
print("=== Sum ===")
total = calculate_sum(1, 2, 3, 4, 5)

print("\n=== Product ===")
product = calculate_product(1, 2, 3, 4, 5)

# Using lambda with map and filter
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Square all numbers
squared = list(map(lambda x: x ** 2, numbers))
print(f"\nSquared: {squared}")

# Keep only even numbers
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(f"Evens: {evens}")

# Even numbers squared
even_squared = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
print(f"Even squared: {even_squared}")

Output:

=== Sum Calling calculate_sum calculate_sum returned 15 === Product Calling calculate_product calculate_product returned 120 Squared: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Evens: [2, 4, 6, 8, 10] Even squared: [4, 16, 36, 64, 100]

What's Next

In the next tutorial, we'll learn about Modules & Packages - how to organize and reuse code across files.

Modules & Packages →

Comments (0)

No comments yet. Be the first to comment!

Leave a comment