You need to sort users by age. Writing a separate get_age() function feels like overkill for one use. Lambda lets you define small functions inline: sorted(users, key=lambda u: u.age).

Basic lambda syntax

Create a small anonymous function.

basic_lambda.py
def main():
    print("=== Basic Lambda ===\n")
    
    # Regular function
    def square(x):
        return x * x
    
    # Lambda equivalent
    square_lambda = lambda x: x * x
    
    # Both work the same!
    print(f"square(5) = {square(5)}")
    print(f"square_lambda(5) = {square_lambda(5)}")
    
    print("\n=== Lambda Syntax ===")
    # lambda arguments: expression
    add = lambda a, b: a + b
    multiply = lambda a, b: a * b
    
    print(f"add(3, 4) = {add(3, 4)}")
    print(f"multiply(3, 4) = {multiply(3, 4)}")
    
    print("\n=== Inline Usage (Most Common) ===")
    numbers = [1, 2, 3, 4, 5]
    
    # Lambda used directly, not assigned
    squared = list(map(lambda x: x ** 2, numbers))
    print(f"Squares of {numbers}: {squared}")
    
    print("\n=== Type Comparison ===")
    print(f"type(square): {type(square)}")
    print(f"type(square_lambda): {type(square_lambda)}")
    print(f"square.__name__: '{square.__name__}'")
    print(f"square_lambda.__name__: '{square_lambda.__name__}'")  # <lambda>

if __name__ == "__main__":
    main()

lambda x: x * 2 is equivalent to def f(x): return x * 2.

lambda Anonymous function: `lambda args: expression`. Single expression, auto-returned.

Lambda as sort key

Use lambda to customize sorting.

sorted_key.py
def main():
    print("=== Lambda as Sort Key ===\n")
    
    # Sort strings by length
    words = ["apple", "pie", "banana", "kiwi"]
    print(f"Original: {words}")
    
    sorted_by_length = sorted(words, key=lambda w: len(w))
    print(f"By length: {sorted_by_length}")
    
    print("\n=== Sort Objects by Attribute ===")
    people = [
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25},
        {"name": "Charlie", "age": 35}
    ]
    
    # Sort by age
    by_age = sorted(people, key=lambda p: p["age"])
    print("By age:")
    for person in by_age:
        print(f"  {person['name']}: {person['age']}")
    
    # Sort by name
    by_name = sorted(people, key=lambda p: p["name"])
    print("\nBy name:")
    for person in by_name:
        print(f"  {person['name']}: {person['age']}")
    
    print("\n=== Reverse Sort ===")
    numbers = [3, 1, 4, 1, 5, 9, 2, 6]
    descending = sorted(numbers, key=lambda x: -x)
    print(f"Descending: {descending}")
    
    # Or use reverse=True
    descending2 = sorted(numbers, reverse=True)
    print(f"With reverse=True: {descending2}")
    
    print("\n=== Complex Sort Key ===")
    students = [
        ("Alice", 85, 22),
        ("Bob", 90, 20),
        ("Charlie", 85, 21)
    ]
    # Sort by grade (desc), then age (asc)
    sorted_students = sorted(students, key=lambda s: (-s[1], s[2]))
    print("By grade (desc), then age (asc):")
    for name, grade, age in sorted_students:
        print(f"  {name}: grade={grade}, age={age}")

if __name__ == "__main__":
    main()

sorted(items, key=lambda x: x.attr) sorts by any attribute or computation.

Lambda with filter and map

Transform and filter collections inline.

filter_map.py
def main():
    print("=== Lambda with filter() ===\n")
    
    numbers = 
    print(f"Numbers: {numbers}")
    
    # Filter positive numbers
    positives = list(filter(lambda x: x > 0, numbers))
    print(f"Positives: {positives}")
    
    # Filter even numbers
    evens = list(filter(lambda x: x % 2 == 0, numbers))
    print(f"Evens: {evens}")
    
    print("\n=== Lambda with map() ===")
    
    # Square each number
    squared = list(map(lambda x: x ** 2, numbers))
    print(f"Squared: {squared}")
    
    # Absolute value
    absolutes = list(map(lambda x: abs(x), numbers))
    print(f"Absolutes: {absolutes}")
    
    print("\n=== Combining filter and map ===")
    
    # Square of positive numbers only
    result = list(map(lambda x: x ** 2, 
                      filter(lambda x: x > 0, numbers)))
    print(f"Squares of positives: {result}")
    
    print("\n=== List Comprehension Alternative ===")
    # Often clearer than map/filter!
    positives_comp = [x for x in numbers if x > 0]
    print(f"Positives (comprehension): {positives_comp}")
    
    squared_comp = [x ** 2 for x in numbers]
    print(f"Squared (comprehension): {squared_comp}")
    
    combined_comp = [x ** 2 for x in numbers if x > 0]
    print(f"Squares of positives (comprehension): {combined_comp}")

if __name__ == "__main__":
    main()
def main():
    print("=== Lambda with filter() ===\n")
    
    numbers = 
    print(f"Numbers: {numbers}")
    
    # Filter positive numbers
    positives = list(filter(lambda x: x > 0, numbers))
    print(f"Positives: {positives}")
    
    # Filter even numbers
    evens = list(filter(lambda x: x % 2 == 0, numbers))
    print(f"Evens: {evens}")
    
    print("\n=== Lambda with map() ===")
    
    # Square each number
    squared = list(map(lambda x: x ** 2, numbers))
    print(f"Squared: {squared}")
    
    # Absolute value
    absolutes = list(map(lambda x: abs(x), numbers))
    print(f"Absolutes: {absolutes}")
    
    print("\n=== Combining filter and map ===")
    
    # Square of positive numbers only
    result = list(map(lambda x: x ** 2, 
                      filter(lambda x: x > 0, numbers)))
    print(f"Squares of positives: {result}")
    
    print("\n=== List Comprehension Alternative ===")
    # Often clearer than map/filter!
    positives_comp = [x for x in numbers if x > 0]
    print(f"Positives (comprehension): {positives_comp}")
    
    squared_comp = [x ** 2 for x in numbers]
    print(f"Squared (comprehension): {squared_comp}")
    
    combined_comp = [x ** 2 for x in numbers if x > 0]
    print(f"Squares of positives (comprehension): {combined_comp}")

if __name__ == "__main__":
    main()
def main():
    print("=== Lambda with filter() ===\n")
    
    numbers = 
    print(f"Numbers: {numbers}")
    
    # Filter positive numbers
    positives = list(filter(lambda x: x > 0, numbers))
    print(f"Positives: {positives}")
    
    # Filter even numbers
    evens = list(filter(lambda x: x % 2 == 0, numbers))
    print(f"Evens: {evens}")
    
    print("\n=== Lambda with map() ===")
    
    # Square each number
    squared = list(map(lambda x: x ** 2, numbers))
    print(f"Squared: {squared}")
    
    # Absolute value
    absolutes = list(map(lambda x: abs(x), numbers))
    print(f"Absolutes: {absolutes}")
    
    print("\n=== Combining filter and map ===")
    
    # Square of positive numbers only
    result = list(map(lambda x: x ** 2, 
                      filter(lambda x: x > 0, numbers)))
    print(f"Squares of positives: {result}")
    
    print("\n=== List Comprehension Alternative ===")
    # Often clearer than map/filter!
    positives_comp = [x for x in numbers if x > 0]
    print(f"Positives (comprehension): {positives_comp}")
    
    squared_comp = [x ** 2 for x in numbers]
    print(f"Squared (comprehension): {squared_comp}")
    
    combined_comp = [x ** 2 for x in numbers if x > 0]
    print(f"Squares of positives (comprehension): {combined_comp}")

if __name__ == "__main__":
    main()

filter(lambda x: x > 0, nums) keeps positives. map(lambda x: x*2, nums) doubles.

higher-order function Function that takes or returns functions. `map`, `filter`, `sorted` accept lambdas.

Multiple arguments in lambda

Lambdas can take multiple (or zero) arguments.

multiple_args.py
def main():
    print("=== Lambda with Multiple Arguments ===\n")
    
    # Two arguments
    add = lambda x, y: x + y
    multiply = lambda x, y: x * y
    
    print(f"add(5, 3) = {add(5, 3)}")
    print(f"multiply(5, 3) = {multiply(5, 3)}")
    
    # Three or more
    volume = lambda l, w, h: l * w * h
    print(f"volume(2, 3, 4) = {volume(2, 3, 4)}")
    
    print("\n=== Lambda with No Arguments ===")
    
    get_pi = lambda: 3.14159
    greet = lambda: "Hello, World!"
    
    print(f"get_pi() = {get_pi()}")
    print(f"greet() = {greet()}")
    
    print("\n=== Lambda with Default Arguments ===")
    
    power = lambda x, n=2: x ** n
    print(f"power(5) = {power(5)}")       # 5^2 = 25
    print(f"power(5, 3) = {power(5, 3)}") # 5^3 = 125
    
    greet_person = lambda name, greeting="Hello": f"{greeting}, {name}!"
    print(greet_person("Alice"))
    print(greet_person("Bob", "Hi"))
    
    print("\n=== Practical: reduce() ===")
    from functools import reduce
    
    numbers = [1, 2, 3, 4, 5]
    
    # Sum using reduce
    total = reduce(lambda acc, x: acc + x, numbers)
    print(f"Sum of {numbers} = {total}")
    
    # Product using reduce
    product = reduce(lambda acc, x: acc * x, numbers)
    print(f"Product of {numbers} = {product}")
    
    # Max using reduce
    maximum = reduce(lambda a, b: a if a > b else b, numbers)
    print(f"Max of {numbers} = {maximum}")

if __name__ == "__main__":
    main()

lambda a, b: a + b takes two args. lambda: 42 takes none.

Common lambda patterns

Frequently used lambda idioms.

common_patterns.py
def main():
    print("=== Common Lambda Patterns ===\n")
    
    # Pattern 1: Getter/accessor
    print("=== Getter Pattern ===")
    users = [
        {"name": "Alice", "score": 85},
        {"name": "Bob", "score": 92},
        {"name": "Charlie", "score": 78}
    ]
    
    names = list(map(lambda u: u["name"], users))
    print(f"Names: {names}")
    
    top_scorer = max(users, key=lambda u: u["score"])
    print(f"Top scorer: {top_scorer['name']}")
    
    # Pattern 2: Conditional expression
    print("\n=== Conditional Pattern ===")
    numbers = [-3, -1, 0, 2, 5]
    
    # Ternary in lambda
    signs = list(map(lambda x: "pos" if x > 0 else ("neg" if x < 0 else "zero"), 
                     numbers))
    print(f"Numbers: {numbers}")
    print(f"Signs: {signs}")
    
    # Pattern 3: Method call
    print("\n=== Method Call Pattern ===")
    words = ["Hello", "WORLD", "Python"]
    
    lowered = list(map(lambda s: s.lower(), words))
    print(f"Lowered: {lowered}")
    
    # Pattern 4: Tuple operations
    print("\n=== Tuple Pattern ===")
    pairs = [(1, "b"), (3, "a"), (2, "c")]
    
    # Sort by second element
    by_second = sorted(pairs, key=lambda p: p[1])
    print(f"By second element: {by_second}")
    
    # Pattern 5: Composition
    print("\n=== Composition Pattern ===")
    
    # Chain operations
    process = lambda x: x.strip().lower().replace(" ", "_")
    
    titles = ["  Hello World  ", " Python CODE ", "  DATA Science  "]
    slugs = list(map(process, titles))
    print(f"Slugs: {slugs}")

if __name__ == "__main__":
    main()

Key extraction, default values, and simple transformations are common uses.

Exercise: limitations.py

Explore when NOT to use lambda - prefer def for complex logic