Skip to content

Latest commit

 

History

History
117 lines (75 loc) · 3.88 KB

File metadata and controls

117 lines (75 loc) · 3.88 KB

Lambda (Anonymous) functions and Higher-Order Functions.

In Python, functions are "first-class citizens," meaning they can be passed around just like integers or strings. This flexibility leads us to two powerful concepts: Lambda (Anonymous) functions and Higher-Order Functions.


1. Anonymous Functions (The lambda)

A Lambda is a small, one-line function that doesn't have a name. You use it when you need a simple piece of logic for a short period and don't want to define a full function using def.

Syntax: lambda arguments : expression

Different Parameter Variations

Type Example Code Logic
Zero Parameters greet = lambda: "Hello!" Returns "Hello!" whenever called.
Single Parameter square = lambda x: x * x Takes , returns .
Multiple Parameters add = lambda x, y, z: x + y + z Sums three numbers.
Default Parameters power = lambda x, n=2: x ** n Squares by default, but can be changed.
Variable Args (*args) sum_all = lambda *args: sum(args) Takes any number of inputs.

2. Higher-Order Functions (HOF)

A function is "Higher-Order" if it does at least one of the following:

  1. Takes one or more functions as arguments.
  2. Returns a function as its result.

Example A: Functions as Arguments (Built-ins)

Python has built-in HOFs like map(), filter(), and sorted().

numbers = [1, 2, 3, 4, 5, 6]

# 1. filter: Takes a function that returns True/False
evens = list(filter(lambda x: x % 2 == 0, numbers)) 

# 2. map: Applies a function to every item
doubled = list(map(lambda x: x * 2, numbers))

# 3. sorted: Uses a 'key' function to determine sort order
points = [(1, 2), (3, 1), (5, 10)]
# Sort by the second element of the tuple
sorted_points = sorted(points, key=lambda point: point[1])

print(f"Evens: {evens}")
print(f"Doubled: {doubled}")
print(f"Sorted by Y: {sorted_points}")

Example B: Returning a Function (Closures)

This is a "Function Factory." The HOF creates and returns a specialized function.

def make_multiplier(n):
    # This HOF returns a lambda function
    return lambda x: x * n

double = make_multiplier(2)
triple = make_multiplier(3)

print(double(10)) # Output: 20
print(triple(10)) # Output: 30

3. Combining Everything: Real-World Way

In professional code, you often see these used together to process complex data, like a list of dictionaries (common in Web APIs).

The Scenario: Filtering and Formatting User Data

users = [
    {"name": "Alice", "age": 25, "role": "admin"},
    {"name": "Bob", "age": 17, "role": "user"},
    {"name": "Charlie", "age": 30, "role": "user"},
    {"name": "David", "age": 15, "role": "admin"},
]

# Task: Get names of all ADULT admins
# 1. Filter for adults (age >= 18) AND role is admin
# 2. Map to extract only the name
logic = lambda u: u['age'] >= 18 and u['role'] == 'admin'

adult_admins = list(map(lambda u: u['name'], filter(logic, users)))

print(f"Adult Admins: {adult_admins}") # Output: ['Alice']

How to Understand the Logic

Think of it like a Conveyor Belt:

  1. The List is the raw material on the belt.
  2. The HOF (map/filter) is the machine on the belt.
  3. The Lambda is the specific "instruction" you plug into the machine (e.g., "If it's red, throw it away" or "Paint it blue").

Why Use These?

  • Conciseness: You can do in 1 line what might take 5 lines with a loop.
  • Readability: Once you know the syntax, filter(is_valid, data) is more readable than a long for loop with if statements.
  • Functional Programming: It allows for a style of coding that focuses on "what to do" rather than "how to loop."

A Word of Caution: If your lambda gets too complex (e.g., it has nested logic or is very long), it's better to use a regular def function. Code is read more often than it is written!