Lambda, Recursion & Decorators
Functions ke advanced forms � quick lambda, tree recursion, aur power decorator pattern.
Advanced functions kyun seekhein?
Basic def se tumne functions banana shuru kiya. Ab teen powerful patterns hain jo code ko concise, reusable aur expressive banate hain:
- Lambda � small tasks ke liye quick anonymous function
- Recursion � tree traversal aur divide-and-conquer mein use hota hai
- Decorator � functions ko modify karta hai bina unhe change kiye
In patterns ko samajhna chahta hai to concept grid dekho:
lambda x: x*2 � anonymous function, kabhi kabhi named function likhne ki zaroorat nahi.
Function khud ko call karta hai � har call chhota hota hai jab tak base case na aaye.
Function wrapper jo extra behavior add karta hai � logging, timing, authentication.
Lambda: anonymous function
Lambda ek small function hai jo bina naam ke hota hai. Jaise sticky note � ek kaam karo aur phek do.
# Lambda � single expression
double = lambda x: x * 2
print(double(5)) # 10
# Lambda with map/filter
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # [1, 4, 9, 16, 25]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]Lambda ka syntax: lambda parameters: expression. Ek hi expression hota hai, multiple lines nahi. map() har element par lambda apply karta hai, filter() sirf true wale rakhta hai.
map/filter mein quick transformation, ya callback functions mein. Complex logic ho to named def function better hai.Recursion: function khud ko call kare
Recursion mein function apne aap ko chhota version mein call karta hai. Har recursive call ke liye ek base case zaroori hai � warna infinite loop ho jayega.
# Factorial: n! = n � (n-1)!
def factorial(n):
if n <= 1: # base case
return 1
return n * factorial(n - 1) # recursive case
print(factorial(5)) # 120
# Fibonacci: 0, 1, 1, 2, 3, 5, 8...
def fibonacci(n):
if n <= 0:
return 0
if n == 1:
return 1
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(6)) # 8Factorial example mein: factorial(5) calls 5 * factorial(4), jo calls 4 * factorial(3), aur aise chalta hai jab tak factorial(1) return 1 na kare � woh hai base case.
Recursion real use-cases
Recursion tab useful hai jab problem naturally divide ho chhoti sub-problems mein:
# Directory traversal (conceptual)
def count_files(folder):
count = 0
for item in folder:
if item.is_file():
count += 1
elif item.is_dir():
count += count_files(item) # recursive call
return count
# Sum of list elements
def list_sum(nums):
if len(nums) == 0:
return 0
return nums[0] + list_sum(nums[1:])
print(list_sum([1, 2, 3, 4, 5])) # 15
# Power calculation
def power(base, exp):
if exp == 0:
return 1
return base * power(base, exp - 1)
print(power(2, 10)) # 1024Har example mein pattern same hai: base case check karo, warna chhoti problem solve karo aur result jodo.
Decorator: function ka wrapper
Decorator ek function hai jo doosre function ko leta hai, usme kuch add karta hai, aur naya wrapped function return karta hai. @ syntax se use hota hai.
# Timer decorator
def timer(func):
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {end-start:.4f}s")
return result
return wrapper
@timer
def slow_function():
import time
time.sleep(0.1)
return "done"
print(slow_function())@timer exactly same hai jaise slow_function = timer(slow_function). Wrapper function call karne par pehle timer start hota hai, phir original function run hota hai, phir time print hota hai.
Decorators ke real examples
# Logger decorator
def logger(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@logger
def add(a, b):
return a + b
add(3, 5)
# Output:
# Calling add with (3, 5), {}
# add returned 8
# Cache decorator (memoization)
def cache(func):
memo = {}
def wrapper(*args):
if args not in memo:
memo[args] = func(*args)
return memo[args]
return wrapper
@cache
def fibonacci(n):
if n <= 0:
return 0
if n == 1:
return 1
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(50)) # Instant! Without cache bahut slow hotaDecorators se tumhe function ke andar logging, caching, ya authentication jaise cross-cutting concerns milte hain bina business logic change kiye.
Concept grid: quick recap
lambda x: x*2 � quick anonymous function, map/filter mein use karo.
Function khud ko call kare � base case zaroori hai, tree/graph problems mein best.
@decorator se function ko wrap karo � logging, timing, caching add karo.
Quick check
Lambda function likho jo number ka square kare.
lambda keyword, ek parameter, colon, aur expression x**2 ya x*x.
Common mistakes
- Lambda mein multiple statements likhna � lambda sirf ek expression support karta hai.
- Recursion mein base case bhoolna � infinite recursion aur stack overflow.
- Decorator mein
*args, **kwargsna dena � wrapper sirf fixed arguments accept karega. - Recursion ko jab iteration se solve ho sake tab recursion use karna � iteration zyada efficient.
Great. Ab list comprehension, generators aur context managers dekho � aur bhi Pythonic patterns seekho.