ల్యాంబ్డా, రికర్షన్ & ఫంక్షనల్ ప్రోగ్రామింగ్

🌐 Modern Python 3.12+ 📖 Chapter 18 of 25 📁 Phase 04: ఫంక్షన్స్, మాడ్యూల్స్ & ఫైల్ I/O 🗓️ 2026 Edition
📌 Covered in this chapter: Anonymous Lambda Functions · రికర్షన్ & కాల్ స్టాక్ · Higher-order Functions: map(), filter(), reduce() · Closures పరిచయం · Pure Functions & Immutability · Anonymous Lambda Syntax · map(), filter(), and functools.reduce() · Lazy Evaluation Iterators · Recursion Base Cases & Call Stack Limits · Memoization with @functools.lru_cache · Financial Fraud Detection Pipeline
మీరు ఒక చిన్న ఒకే ఒక్క లైన్ గణిత సమీకరణాన్ని రాయడానికి కూడా ప్రతిసారీ def అని పేరు పెట్టి, నాలుగైదు లైన్ల కోడ్ రాయడం కాస్త భారంగా అనిపించిందా? లేదా లక్షల రికార్డులు ఉన్న డేటాసెట్‌పై లూప్‌లు రాయకుండా, అత్యంత క్లీన్‌గా ఒక ఫంక్షనల్ పైప్‌లైన్ ద్వారా డేటాను ఫిల్టర్ చేసి, మార్పిడి చేసి, సారాంశాన్ని బయటకు తీయాలనుకుంటున్నారా?

ఇక్కడే మనకు ఫంక్షనల్ ప్రోగ్రామింగ్ (Functional Programming) పారడైమ్ పరిచయం అవుతుంది! పైథాన్‌లో పేర్లు లేని అజ్ఞాత ఫంక్షన్లను రెప్పపాటులో సృష్టించే lambda ఎక్స్‌ప్రెషన్లు, డేటా స్ట్రీమ్‌లను ప్రాసెస్ చేసే పవిత్ర త్రిమూర్తులు map(), filter(), reduce(), మరియు ఒక పెద్ద సమస్యను తనంతట తానే పిలుచుకుంటూ పరిష్కరించే కళాత్మక విధానం రికర్శన్ (Recursion) ప్రోగ్రామర్‌కు అపరిమితమైన ఆలోచనా స్వేచ్ఛను ఇస్తాయి. ఈ అధ్యాయంలో మనం ఈ ఫంక్షనల్ ఆయుధాలన్నింటినీ అన్వేషిస్తూ, బ్యాంకింగ్ లావాదేవీలలో మోసాలను గుర్తించే పూర్తి స్థాయి ఫ్రాడ్ డిటెక్షన్ పైప్‌లైన్ ప్రాజెక్ట్‌ను నిర్మిద్దాం!

1 ఫంక్షనల్ ప్రోగ్రామింగ్ అంటే ఏమిటి? (Functional Programming Paradigm)

పైథాన్ అనేది ఒక మల్టీ-పారడైమ్ (Multi-paradigm) ప్రోగ్రామింగ్ లాంగ్వేజ్. అంటే ఇందులో ఆబ్జెక్ట్ ఓరియెంటెడ్ కోడింగ్ చేయవచ్చు, అలాగే గణిత ఆధారిత ఫంక్షనల్ ప్రోగ్రామింగ్ (FP) శైలిని కూడా పూర్తి స్థాయిలో అనుసరించవచ్చు.

ఫంక్షనల్ ప్రోగ్రామింగ్ యొక్క ముఖ్య స్తంభాలు:

# స్వచ్ఛమైన ఫంక్షన్ (Pure): సైడ్-ఎఫెక్ట్స్ లేవు
def add_tax(price, tax_rate=0.18):
    return price + (price * tax_rate)

# అపవిత్రమైన ఫంక్షన్ (Impure): బయటి గ్లోబల్ స్టేట్‌ను మారుస్తుంది!
cart_total = 0
def impure_add(price):
    global cart_total
    cart_total += price # Side effect!

2 ల్యాంబ్డా ఫంక్షన్స్ అంటే ఏమిటి? (Anonymous Functions)

పైథాన్‌లో def కీవర్డ్ లేకుండా, పేరు లేకుండా ఒకే ఒక్క లైన్‌లో రాసే చిన్న ఫంక్షన్లను ల్యాంబ్డా ఫంక్షన్స్ (Lambda Functions / Anonymous Functions) అంటారు.

ప్రాథమిక సింటాక్స్:
lambda arguments: expression

3 lambda ఎప్పుడు వాడాలి? PEP 8 గోల్డెన్ రూల్స్

పైథాన్ అధికారిక స్టైల్ గైడ్ PEP 8 ప్రకారం, ల్యాంబ్డా ఫంక్షన్లను వేరియబుల్స్‌కు బైండ్ చేయడానికి వాడకూడదు (ఉదా: f = lambda x: x*2 అని రాయడానికి బదులుగా def f(x): return x*2 రాయాలి).

ల్యాంబ్డా వాడటానికి సరైన సందర్భాలు:

4 map() ఫంక్షన్ — లేజీ ఎవాల్యుయేషన్ & డేటా ట్రాన్స్‌ఫార్మేషన్

map(func, iterable, ...) అనేది ఒక కలెక్షన్‌లోని ప్రతి ఒక్క ఎలిమెంట్‌పై పేర్కొన్న ఫంక్షన్‌ను అప్లై చేసి ఫలితాలను అందిస్తుంది.

5 filter() ఫంక్షన్ — ప్రిడికేట్-బేస్డ్ షరతులతో కూడిన వడపోత

filter(predicate_func, iterable) అనేది ఇచ్చిన షరతును (Boolean Predicate) సంతృప్తిపరిచే ఎలిమెంట్లను మాత్రమే వడపోసి కొత్త ఇటరేటర్‌గా అందిస్తుంది. ఫంక్షన్ ఏ ఎలిమెంట్లకు అయితే True ఇస్తుందో వాటిని మాత్రమే ఉంచి, False లేదా ఫాల్సీ విలువలను తుడిచిపెడుతుంది.

# ఖాళీ స్ట్రింగ్స్ మరియు None విలువలను సులభంగా ఫిల్టర్ చేయడం:
raw_inputs = ["హైదరాబాద్", "", None, "విజయవాడ", False, "తిరుపతి"]
clean_cities = list(filter(None, raw_inputs)) # ఫంక్షన్ స్థానంలో None పెడితే ట్రూతీ విలువలు మాత్రమే వస్తాయి!
print("క్లీన్ సిటీస్ :", clean_cities) # ['హైదరాబాద్', 'విజయవాడ', 'తిరుపతి']

6 functools.reduce() — డేటా అక్యుములేషన్ & రోలింగ్ కంప్యూటేషన్

reduce(func, iterable, [initializer]) అనేది కలెక్షన్‌లోని అంశాలను వరుసగా రెండేసి చొప్పున తీసుకుని ఫంక్షన్ అప్లై చేస్తూ, చివరికి మొత్తం డేటాను ఒకే ఒక్క విలువగా (సింగిల్ అక్యుములేటెడ్ వాల్యూ) కుదిస్తుంది.

అక్యుములేషన్ ఎలా పనిచేస్తుందో చూపే డయాగ్రమ్:

డేటా: [1, 2, 3, 4] ──▶ ఫంక్షన్: lambda acc, x: acc + x
దశ 1: func(1, 2) ──▶ 3
దశ 2: func(3, 3) ──▶ 6
దశ 3: func(6, 4) ──▶ 10 (చివరి ఫలితం!)
⚠️ Initializer ఎందుకు ముఖ్యం: ఖాళీ లిస్ట్‌పై reduce వాడితే TypeError రాకుండా reduce(func, [], 0) అని ఇనిషియలైజర్ ఇవ్వడం ప్రొడక్షన్ బెస్ట్ ప్రాక్టీస్!

7 కోడ్ డెమో 1: map(), filter(), reduce() తో డేటా పైప్‌లైన్

ఉద్యోగుల శాలరీ డేటా నుండి పన్ను మినహాయింపులు చేసి, అర్హులైన వారి మొత్తం వ్యయాన్ని లెక్కించే పైప్‌లైన్ డెమో:

01_functional_pipeline_demo.py
# =====================================================================
# చాప్టర్ 18 డెమో 1: map(), filter(), reduce() ఫంక్షనల్ పైప్‌లైన్
# =====================================================================
from functools import reduce

salaries = [45000, 72000, 38000, 110000, 95000, 28000]

# 1. FILTER: ₹50,000 కంటే ఎక్కువ జీతం ఉన్నవారిని మాత్రమే ఎంపిక చేయడం
high_earners = list(filter(lambda s: s >= 50000, salaries))
print("1. అర్హులైన జీతాలు (>= 50k) :", high_earners)

# 2. MAP: 10% కార్పొరేట్ హైక్ ఇవ్వడం (1.10 తో గుణించడం)
hiked_salaries = list(map(lambda s: round(s * 1.10), high_earners))
print("2. 10% హైక్ తర్వాత జీతాలు   :", hiked_salaries)

# 3. REDUCE: మొత్తం కంపెనీ చెల్లించాల్సిన బడ్జెట్ అక్యుములేషన్
total_payroll = reduce(lambda acc, s: acc + s, hiked_salaries, 0)
print(f"3. మొత్తం బడ్జెట్ వ్యయం     : ₹{total_payroll:,.2f}")

8 రికర్షన్ అంటే ఏమిటి? (What is Recursion in Python?)

ఒక ఫంక్షన్ తన పనిని పూర్తి చేయడానికి తనను తానే పిలుచుకునే (Self-Referential) ప్రోగ్రామింగ్ పద్ధతిని రికర్శన్ (Recursion) అంటారు.

ప్రతి రికర్సివ్ ఫంక్షన్‌లో రెండు విభాగాలు తప్పనిసరి:

9 రికర్షన్ & కాల్ స్టాక్ ఆర్కిటెక్చర్ (sys.getrecursionlimit())

ప్రతి రికర్సివ్ కాల్‌కూ ఒక సరికొత్త స్టాక్ ఫ్రేమ్ మెమరీలో స్టోర్ అవుతుంది. బేస్ కేస్ తగిలేంతవరకు ఆ ఫ్రేమ్‌లు ఏవీ క్లియర్ కావు.

10 కోడ్ డెమో 2: ఫ్యాక్టోరియల్, నెస్టెడ్ డేటా ట్రావర్సల్ రికర్షన్

నెస్టెడ్ డైరెక్టరీలు లేదా కేటగిరీ ట్రీలను రికర్షన్ ద్వారా ఎంత సరళంగా ట్రావర్స్ చేయవచ్చో పరిశీలిద్దాం:

02_recursion_directory_traversal.py
# రికర్సివ్ డేటా స్ట్రక్చర్ ట్రావర్సల్
nested_categories = {
    "ఎలక్ట్రానిక్స్": {
        "మొబైల్స్": ["ఆండ్రాయిడ్", "ఐఫోన్"],
        "ల్యాప్‌టాప్స్": ["గేమింగ్", "అల్ట్రాబుక్స్"]
    },
    "దుస్తులు": {
        "పురుషులు": ["షర్టులు", "జీన్స్"],
        "మహిళలు": ["చీరలు", "కుర్తీలు"]
    }
}

def print_category_tree(tree, indent_level=0):
    """నెస్టెడ్ డిక్షనరీ ట్రీని రికర్సివ్‌గా ప్రింట్ చేస్తుంది."""
    indent = "    " * indent_level
    if isinstance(tree, dict):
        for key, value in tree.items():
            print(f"{indent}📁 [{key}]")
            print_category_tree(value, indent_level + 1) # Recursive Call
    elif isinstance(tree, list):
        for item in tree:
            print(f"{indent}  📄 {item}") # Base Case Leaf

print("=== రిటైల్ స్టోర్ కేటగిరీ ట్రీ (Recursive Walk) ===")
print_category_tree(nested_categories)

11 ఫంక్షనల్ మెమోయిజేషన్ & functools.partial (Currying)

ఫిబోనాకి వంటి సమస్యలలో సాధారణ రికర్షన్ $O(2^N)$ ఘాతాంక సమయం తీసుకుంటుంది (ఒకే లెక్కను లక్షల సార్లు పునరావృతం చేస్తుంది).

పైథాన్‌లోని @functools.lru_cache డెకరేటర్ గతంలో లెక్కించిన ఫలితాలను మెమరీలో క్యాష్ చేసి, రికర్షన్ వేగాన్ని O(N) లీనియర్ టైమ్‌కు పెంచుతుంది!

from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n):
    if n <= 1: return n
    return fib(n - 1) + fib(n - 2) # మెమోయిజేషన్ వల్ల మైక్రోసెకన్లలో రన్ అవుతుంది!

functools.partial ద్వారా ఫంక్షన్ కరియింగ్ (Function Currying):
ఒక ఫంక్షన్‌లోని కొన్ని ఆర్గ్యుమెంట్లను ముందుగానే ఫిక్స్ చేసి, తక్కువ ఆర్గ్యుమెంట్లు తీసుకునే ఒక సరికొత్త ప్రత్యేక ఫంక్షన్‌ను రూపొందించడాన్ని Partial Application అంటారు:

from functools import partial

def multiply(x, y): return x * y
double = partial(multiply, 2) # x=2 గా ఫిక్స్ చేయబడింది!
triple = partial(multiply, 3)
print("డబుల్ :", double(25)) # 50
print("ట్రిపుల్ :", triple(25)) # 75

12 కామన్ బిగినర్స్ మిస్టేక్స్ & The Closure Late-Binding Trap

13 రియల్-వరల్డ్ ప్రాజెక్ట్: "Enterprise Financial Ledger & Fraud Detection Pipeline"

ఈ పద్దెనిమిదవ అధ్యాయంలో నేర్చుకున్న అన్ని అంశాలను (ల్యాంబ్డా, map, filter, functools.reduce, ప్యూర్ ఫంక్షన్లు, రికర్సివ్ ఆడిట్) అనుసంధానిస్తూ — అనుమానాస్పద లావాదేవీలను గుర్తించి, కరెన్సీ కన్వర్షన్ చేసి, బ్యాలెన్స్ లెడ్జర్‌ను ఆడిట్ చేసే పూర్తి స్థాయి Enterprise Fraud Detection Pipeline Engine ను నిర్మిద్దాం!

03_financial_fraud_detection_engine.py
# =====================================================================
# చాప్టర్ 18 మినీ ప్రాజెక్ట్: Financial Ledger & Fraud Detection Pipeline
# కాన్సెప్ట్స్: Anonymous Lambdas, map(), filter(), functools.reduce(),
#             Pure Functions, Recursive Account Reconciliation
# =====================================================================
from functools import reduce
from datetime import datetime

# బ్యాంకింగ్ లావాదేవీల డేటాసెట్
RAW_TRANSACTIONS = [
    {"id": "TXN-101", "user": "విజయ్", "amount_usd": 120.0, "status": "APPROVED", "is_international": False},
    {"id": "TXN-102", "user": "ఆనంద్", "amount_usd": 4500.0, "status": "APPROVED", "is_international": True}, # Suspicious High Value!
    {"id": "TXN-103", "user": "శ్రీధర్", "amount_usd": 15.0, "status": "REJECTED", "is_international": False},
    {"id": "TXN-104", "user": "హరిత", "amount_usd": 850.0, "status": "APPROVED", "is_international": False},
    {"id": "TXN-105", "user": "ఆనంద్", "amount_usd": 9200.0, "status": "APPROVED", "is_international": True}, # Fraud Alert!
    {"id": "TXN-106", "user": "దివ్య", "amount_usd": 340.0, "status": "APPROVED", "is_international": False}
]

USD_TO_INR = 83.50

def run_fraud_and_ledger_pipeline():
    print("\n" + "=" * 74)
    print(f"{'🏦 మన బ్యాంకింగ్ — ఫైనాన్షియల్ లెడ్జర్ & ఫ్రాడ్ డిటెక్షన్ 2026':^74}")
    print("=" * 74)

    # 1. FILTER: ఆమోదించబడిన (APPROVED) లావాదేవీలను మాత్రమే వడపోయడం
    approved_txns = list(filter(lambda t: t["status"] == "APPROVED", RAW_TRANSACTIONS))
    print(f"మొత్తం లావాదేవీలు: {len(RAW_TRANSACTIONS)} | ఆమోదించబడినవి: {len(approved_txns)}")

    # 2. MAP: USD నుండి INR కరెన్సీ కన్వర్షన్ చేసి నూతన లెడ్జర్ రికార్డులను సృష్టించడం (Pure Function)
    inr_ledger = list(map(
        lambda t: {
            "id": t["id"],
            "user": t["user"],
            "amount_inr": round(t["amount_usd"] * USD_TO_INR, 2),
            "is_intl": t["is_international"],
            "risk_score": "HIGH" if (t["amount_usd"] > 3000 and t["is_international"]) else "NORMAL"
        },
        approved_txns
    ))

    # 3. FILTER: ఫ్రాడ్ అలర్ట్స్ (అంతర్జాతీయ హై-వాల్యూ రిస్క్ ట్రాన్సాక్షన్స్)
    fraud_alerts = list(filter(lambda r: r["risk_score"] == "HIGH", inr_ledger))

    # 4. REDUCE: మొత్తం సెటిల్ అయిన నికర లావాదేవీల విలువ (INR)
    total_turnover_inr = reduce(lambda acc, item: acc + item["amount_inr"], inr_ledger, 0.0)

    # ఆడిట్ నివేదిక ప్రింట్ చేయడం
    print("-" * 74)
    print(f"{'TXN ID':<10} {'వినియోగదారుడు':<16} {'మొత్తం (₹)':>14} {'రకం':<14} {'రిస్క్ స్థాయి':^14}")
    print("-" * 74)

    for record in inr_ledger:
        intl_badge = "అంతర్జాతీయ" if record["is_intl"] else "దేశీయ"
        risk_badge = "🚨 హై రిస్క్!" if record["risk_score"] == "HIGH" else "✅ క్లీన్"
        print(f"{record['id']:<10} {record['user']:<16} ₹{record['amount_inr']:>12,.2f} {intl_badge:<14} {risk_badge:^14}")

    print("=" * 74)
    print(f"మొత్తం టర్నోవర్ క్లియరెన్స్ : ₹{total_turnover_inr:,.2f}")
    print("-" * 74)

    print("\n🚨 అత్యవసర సెక్యూరిటీ సమీక్షకు పంపబడిన అనుమానాస్పద లావాదేవీలు:")
    for alert in fraud_alerts:
        print(f"  • [{alert['id']}] ఖాతాదారు: {alert['user']:<12} మొత్తం: ₹{alert['amount_inr']:,.2f} (అంతర్జాతీయ బదిలీ)")

    print("=" * 74)
    print(f"{'✅ ఫైనాన్షియల్ లెడ్జర్ ఆడిట్ విజయవంతంగా పూర్తయింది!':^74}")
    print("=" * 74 + "\n")

run_fraud_and_ledger_pipeline()

★ ఈ అధ్యాయంపై ప్రాక్టీస్ క్విజ్ (Knowledge Check)

1. ల్యాంబ్డా ఫంక్షన్‌లో return స్టేట్‌మెంట్‌ను ఎందుకు రాయకూడదు?
సమాధానం: ల్యాంబ్డా అనేది సింగిల్ ఎక్స్‌ప్రెషన్ కోసం ఉద్దేశించబడింది. ఆ ఎక్స్‌ప్రెషన్ యొక్క ఫలితం స్వయంచాలకంగా ఇంప్లిసిట్‌గా రిటర్న్ అవుతుంది. అక్కడ return అని రాస్తే పైథాన్ SyntaxError విసురుతుంది.
2. map() ఫంక్షన్ యొక్క లేజీ ఎవాల్యుయేషన్ (Lazy Evaluation) ప్రయోజనం ఏమిటి?
సమాధానం: map() అన్ని అంశాలను ఒకేసారి మెమరీలోకి లోడ్ చేసి లిస్ట్‌గా మార్చదు; అడిగినప్పుడు మాత్రమే ఒక్కొక్క ఎలిమెంట్‌ను ఉత్పత్తి చేసే ఇటరేటర్‌ను ఇస్తుంది. దీనివల్ల జీబీ పరిమాణంలో ఉన్న భారీ డేటాసెట్లను తక్కువ రామ్ (RAM) మెమరీతో సమర్థవంతంగా ప్రాసెస్ చేయవచ్చు.
3. రికర్సివ్ ఫంక్షన్‌లో బేస్ కేస్ (Base Case) లేకపోతే ఏం జరుగుతుంది?
సమాధానం: బేస్ కేస్ లేకపోతే ఫంక్షన్ అనంతంగా కాల్ అవుతూ ఉంటుంది. పైథాన్ కాల్ స్టాక్ లిమిట్ (1000) ను దాటగానే ఇంటర్ప్రెటర్ RecursionError: maximum recursion depth exceeded విసిరి ప్రోగ్రామ్‌ను ఆపేస్తుంది.
4. functools.reduce() ఫంక్షన్ ఏం చేస్తుంది?
సమాధానం: ఇది కలెక్షన్‌లోని అంశాలను వరుసగా రెండేసి చొప్పున తీసుకుని ఫంక్షన్ అప్లై చేస్తూ, చివరికి మొత్తం డేటాను ఒకే ఒక్క విలువగా (సింగిల్ అక్యుములేటెడ్ వాల్యూ) కుదిస్తుంది.
5. @functools.lru_cache రికర్సివ్ ఫంక్షన్లను ఎలా వేగవంతం చేస్తుంది?
సమాధానం: ఇది మెమోయిజేషన్ (Memoization) పద్ధతిని ఉపయోగిస్తుంది. గతంలో లెక్కించిన ఇన్‌పుట్‌లకు సంబంధించిన ఫలితాలను మెమరీలో క్యాష్ చేస్తుంది. తిరిగి అదే ఇన్‌పుట్ వచ్చినప్పుడు మళ్లీ రికర్షన్ చేయకుండా క్యాష్ నుండి తక్షణమే ఫలితాన్ని ఇస్తుంది.
← మునుపటి అధ్యాయం: 17. *args, **kwargs & Scope తర్వాతి అధ్యాయం: 19. మాడ్యూల్స్, ప్యాకేజీలు & pip →

ఈ Financial Fraud Detection Engine ని లైవ్‌గా మన కంపైలర్‌లో రన్ చేయండి!

ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్‌లోనే Modern Python 3 కంపైలర్‌లో ఈ కోడ్‌ను ఎగ్జిక్యూట్ చేసి అవుట్‌పుట్ తనిఖీ చేయండి.