IlmHamroh
Python kursi/Funksiyalar10/14-dars35 daqiqa
Mundarija (21)

7.10-dars: lambda — anonim funksiya

7-QISM — FUNKSIYALAR · 10-dars


1. Kirish va motivatsiya

Ba'zan funksiya shunchalik kichikki, unga nom berish ortiqcha:

python
# def bilan
def uzunlik(s):
    return len(s)

sozlar.sort(key=uzunlik)

# lambda bilan
sozlar.sort(key=lambda s: len(s))

# yoki umuman
sozlar.sort(key=len)

lambda — bir ifodadan iborat anonim funksiya.

Lekin u tez suiiste'mol qilinadi:

python
# ❌ Nomga bog'lash
kvadrat = lambda x: x ** 2          # nega def emas?

# ❌ Murakkab mantiq
f = lambda x: (x ** 2 if x > 0 else -x ** 2) if x != 0 else 0

# ❌ Yon ta'sir
lambda x: print(x)                  # lambda qiymat uchun

# ❌ Ortiqcha o'rash
sorted(r, key=lambda x: len(x))     # key=len yetarli

Va cheklovlar:

python
lambda x: x = 1                     # ❌ o'zlashtirish yo'q
lambda x: return x                  # ❌ return yo'q
lambda x:                           # ❌ tana bo'sh bo'lolmaydi
    print(x)

Bu darsda:

  • lambda sintaksisi va cheklovlari
  • Qachon ishlatish, qachon def
  • key= funksiyasi — asosiy qo'llanish
  • Kech bog'lanish va yopilmalar
  • lambda vs operator moduli
  • PEP 8 tavsiyalari

2. Nazariya — chuqur tushuntirish

2.1. Sintaksis

python
lambda ARGUMENTLAR: IFODA
python
lambda: 42                          # argumentsiz
lambda x: x ** 2                    # bitta argument
lambda x, y: x + y                  # ikkita
lambda x, y=2: x ** y               # sukut qiymat
lambda *args: sum(args)             # *args
lambda **kw: kw                     # **kwargs
lambda x, /, y, *, z: x + y + z     # / va * ham ishlaydi

lambda — ifoda, funksiya obyekti qaytaradi:

python
f = lambda x: x ** 2
type(f)                             # <class 'function'>
f(5)                                # 25
f.__name__                          # '<lambda>'

def bilan farqi — faqat sintaksis:

python
def f(x):
    return x ** 2

g = lambda x: x ** 2

f.__code__.co_code == g.__code__.co_code    # True — bir xil bytecode

Yagona farq: __name__ ('f' vs '<lambda>') va def — buyruq, lambda — ifoda.

2.2. Cheklovlar

1. Faqat bitta IFODA:

python
lambda x: x + 1                     # ✅
lambda x: (x + 1, x + 2)            # ✅ tuple — bitta ifoda
lambda x: [f(i) for i in range(x)]  # ✅ generator — ifoda
lambda x: x if x > 0 else -x        # ✅ shartli ifoda

2. return yo'q — ifoda avtomatik qaytariladi:

python
lambda x: return x                  # ❌ SyntaxError
lambda x: x                         # ✅

3. O'zlashtirish yo'q:

python
lambda x: y = x                     # ❌ SyntaxError
lambda x: (y := x)                  # ✅ walrus (3.8+) — lekin uslub yomon

4. Buyruqlar yo'q:

python
lambda x: if x: ...                 # ❌
lambda x: for i in x: ...           # ❌
lambda x: raise ValueError          # ❌
lambda x: pass                      # ❌
lambda: global x                    # ❌
lambda x: import os                 # ❌

Muqobillar:

python
lambda x: x if x > 0 else 0                 # if o'rniga shartli ifoda
lambda x: [f(i) for i in x]                 # for o'rniga generator
lambda: (_ for _ in ()).throw(ValueError()) # ⚠️ raise hiylasi — QILMANG
lambda: None                                # pass o'rniga

5. Docstring yo'q:

python
f = lambda x: x
f.__doc__                           # None

6. Tur ko'rsatkichlari yo'q:

python
lambda x: int -> int                # ❌ SyntaxError

f: Callable[[int], int] = lambda x: x       # ✅ o'zgaruvchi darajasida

7. Ko'p qatorli bo'lolmaydi (qavs ichida bo'lsa ham o'qilmaydi):

python
f = lambda x: (
    x ** 2
    if x > 0
    else -x ** 2
)                                   # ⚠️ ishlaydi, lekin def yaxshiroq

2.3. Qachon ishlatish

Asosiy qo'llanish — key= funksiyasi:

python
sorted(xodimlar, key=lambda x: x.maosh)
max(sozlar, key=lambda s: len(s))
min(nuqtalar, key=lambda p: p.x ** 2 + p.y ** 2)
sorted(d.items(), key=lambda kv: -kv[1])
groupby(malumot, key=lambda x: x.turi)

Bir martalik callback:

python
tugma.bosilganda = lambda: print("bosildi")
threading.Timer(5, lambda: saqla(malumot))

Qisqa transformatsiya:

python
list(map(lambda x: x * 2, r))       # ⚠️ [x*2 for x in r] yaxshiroq
filter(lambda x: x > 0, r)          # ⚠️ [x for x in r if x>0] yaxshiroq

defaultdict sukut qiymati:

python
defaultdict(lambda: defaultdict(int))
defaultdict(lambda: [0] * 3)

Funksiya generatsiya qilish:

python
kopaytiruvchilar = {n: (lambda x, n=n: x * n) for n in range(1, 4)}

Qachon ISHLATMASLIK:

1. Nomga bog'lash (PEP 8 E731):

python
kvadrat = lambda x: x ** 2          # ❌ E731

def kvadrat(x):                     # ✅
    return x ** 2

Sabab: def docstring, tur ko'rsatkichlari, aniq __name__ va traceback beradi.

2. Tayyor funksiya bor bo'lganda:

python
key=lambda x: len(x)                # ❌
key=len                             # ✅

key=lambda x: x[1]                  # ❌
key=itemgetter(1)                   # ✅ tezroq

key=lambda x: x.maosh               # ❌
key=attrgetter("maosh")             # ✅

lambda x: -x                        # ❌
operator.neg                        # ✅

3. Murakkab mantiq:

python
lambda x: (a if p(x) else b if q(x) else c)     # ❌ o'qib bo'lmaydi

4. Yon ta'sir:

python
lambda x: print(x)                  # ❌ lambda qiymat uchun
[lambda: d.update(...)]             # ❌

5. Argumentsiz konstanta:

python
lambda: 0                           # ⚠️
defaultdict(int)                    # ✅

2.4. operator moduli

Ko'p lambda uchun tayyor va tezroq muqobil bor:

python
from operator import (
    itemgetter, attrgetter, methodcaller,
    add, sub, mul, truediv, neg, not_,
    lt, le, eq, ne, ge, gt,
    and_, or_, xor, contains,
)
lambda operator
lambda x: x[1] itemgetter(1)
lambda x: (x[0], x[2]) itemgetter(0, 2)
lambda x: x.maosh attrgetter("maosh")
lambda x: x.a.b attrgetter("a.b")
lambda x: x.upper() methodcaller("upper")
lambda x: x.count("a") methodcaller("count", "a")
lambda a, b: a + b add
lambda x: -x neg
lambda a, b: a < b lt

Tezlik farqi (~20-30%):

python
sorted(r, key=lambda x: x[1])       # ~1.3x
sorted(r, key=itemgetter(1))        # ~1.0x  ⭐

Sabab: itemgetter — C da yozilgan, Python freym yaratilmaydi.

Lekin o'qilishi kontekstga bog'liq:

python
key=itemgetter(1)                   # ⚠️ 1 nima?
key=lambda x: x.maosh               # ✅ ravshan
key=attrgetter("maosh")             # ✅ ham ravshan

2.5. Yopilma va kech bog'lanish

lambda — oddiy funksiya, u ham yopilma yaratadi:

python
def kopaytiruvchi(n):
    return lambda x: x * n          # n ni eslab qoladi

ikkilash = kopaytiruvchi(2)
ikkilash(5)                         # 10

Kech bog'lanish (6.15, 7.8-darslar):

python
funksiyalar = [lambda: i for i in range(3)]
[f() for f in funksiyalar]          # [2, 2, 2]  ⚠️

Yechimlar:

python
[lambda i=i: i for i in range(3)]           # ✅ sukut argument
[partial(lambda x: x, i) for i in range(3)] # ✅ partial
[(lambda n: lambda: n)(i) for i in range(3)] # ✅ ikki qavat lambda

Siklda ham:

python
handlers = {}
for nom in ["a", "b"]:
    handlers[nom] = lambda: nom     # ⚠️ hammasi "b"

for nom in ["a", "b"]:
    handlers[nom] = lambda n=nom: n # ✅

2.6. lambda va map/filter

python
list(map(lambda x: x * 2, r))
list(filter(lambda x: x > 0, r))

Generator ko'pincha yaxshiroq (6.15-dars):

python
[x * 2 for x in r]                  # ✅ o'qilishi yaxshi, tezroq
[x for x in r if x > 0]             # ✅

map/filter qachon yaxshiroq:

python
map(str.upper, sozlar)              # ✅ tayyor funksiya
map(int, satrlar)                   # ✅
filter(None, r)                     # ✅ bo'sh qiymatlarni olib tashlaydi
map(f, a, b)                        # ✅ bir necha iterable

lambda bilan map — deyarli har doim generator yaxshiroq:

python
list(map(lambda x: x * 2, r))       # ❌ uzunroq va sekinroq
[x * 2 for x in r]                  # ✅

functools.reduce:

python
from functools import reduce
reduce(lambda a, b: a + b, r)       # ⚠️ sum(r) yaxshiroq
reduce(lambda a, b: a * b, r)       # ✅ math.prod(r) (3.8+)
reduce(lambda a, b: a | b, toplamlar)   # ✅ maxsus amal

12-darsda batafsil.

2.7. Nozikliklar

1. lambda da *args, **kwargs, /, *:

python
lambda *args, **kw: (args, kw)      # ✅
lambda x, /, y, *, z: x + y + z     # ✅ (3.8+)

2. Bir necha lambda zanjiri:

python
kompozitsiya = lambda f, g: lambda x: f(g(x))
ikkilash_va_qosh = kompozitsiya(lambda x: x + 1, lambda x: x * 2)
ikkilash_va_qosh(5)                 # 11

O'qilishi yomon — def yoki functools yaxshiroq.

3. Rekursiv lambda:

python
# ❌ To'g'ridan-to'g'ri mumkin emas
fakt = lambda n: 1 if n < 2 else n * fakt(n - 1)     # ⚠️ ishlaydi, lekin
# `fakt` global nomga bog'liq — o'zgarsa buziladi

Y-kombinator (nazariy):

python
Y = lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v)))
fakt = Y(lambda f: lambda n: 1 if n < 2 else n * f(n - 1))

Bu — funksional dasturlash mashqi, amaliy kod emas.

4. lambda sinf ichida:

python
class A:
    kvadrat = lambda self, x: x ** 2     # ⚠️ metod bo'ladi
    statik = staticmethod(lambda x: x)   # ✅

5. Sukut argument — def kabi:

python
f = lambda r=[]: r.append(1)        # ⚠️ o'zgaruvchan sukut tuzog'i (7.3-dars)

6. Traceback da ko'rinishi:

python
f = lambda x: 1 / x
f(0)
# ZeroDivisionError: division by zero
#   File "...", line N, in <lambda>      ← nomsiz

def bilan funksiya nomi ko'rinadi — debug oson.


3. Tez ma'lumotnoma

Sintaksis

python
lambda ARGUMENTLAR: IFODA

lambda: 42                      argumentsiz
lambda x: x ** 2
lambda x, y=2: x ** y
lambda *args, **kw: ...
lambda x, /, y, *, z: ...       (3.8+)

Cheklovlar

Faqat BITTA IFODA
❌ return, o'zlashtirish, if/for/raise/pass/global/import
❌ docstring, tur ko'rsatkichlari
❌ ko'p qator

✅ Shartli ifoda:  lambda x: a if p else b
✅ Generator:      lambda x: [f(i) for i in x]

Qachon ishlatish

✅ key= funksiyasi           sorted(r, key=lambda x: x.maosh)
✅ Bir martalik callback     Timer(5, lambda: f())
✅ defaultdict sukuti        defaultdict(lambda: defaultdict(int))

❌ Nomga bog'lash            f = lambda x: ...   (PEP 8 E731)
❌ Tayyor funksiya bor       key=len, key=itemgetter(1)
❌ Murakkab mantiq
❌ Yon ta'sir                lambda: print(x)

operator moduli (tezroq)

python
lambda x: x[1]          →  itemgetter(1)
lambda x: x.maosh       →  attrgetter("maosh")
lambda x: x.upper()     →  methodcaller("upper")
lambda a,b: a+b         →  add
lambda x: -x            →  neg

Kech bog'lanish

python
[lambda: i for i in range(3)]       → [2, 2, 2]
[lambda i=i: i for i in range(3)]   → [0, 1, 2]  ✅

map/filter

python
list(map(lambda x: x*2, r))     ❌ → [x*2 for x in r]  ✅
map(str.upper, sozlar)          ✅ tayyor funksiya
filter(None, r)                 ✅ bo'shlarni olib tashlaydi

4. Batafsil misollar

Misol 1 — Sintaksis va cheklovlar

python
"""lambda ning barcha shakllari va chegaralari."""

import dis
import inspect

print("=== 1. Barcha shakllar ===")

SHAKLLAR = [
    ("lambda: 42",                      lambda: 42,                 ()),
    ("lambda x: x ** 2",                lambda x: x ** 2,           (5,)),
    ("lambda x, y: x + y",              lambda x, y: x + y,         (2, 3)),
    ("lambda x, y=10: x ** y",          lambda x, y=10: x ** y,     (2,)),
    ("lambda *args: sum(args)",         lambda *args: sum(args),    (1, 2, 3)),
    ("lambda **kw: len(kw)",            lambda **kw: len(kw),       ()),
    ("lambda x, /, y: x - y",           lambda x, /, y: x - y,      (10, 3)),
    ("lambda *, x: x * 2",              lambda *, x: x * 2,         ()),
]

print(f"  {'Shakl':<30} {'Imzo':<24} {'Natija'}")
print("  " + "─" * 68)
for kod, f, args in SHAKLLAR:
    try:
        if "**kw" in kod:
            natija = f(a=1, b=2)
        elif "*, x" in kod:
            natija = f(x=5)
        else:
            natija = f(*args)
    except TypeError as e:
        natija = f"❌ {e}"
    print(f"  {kod:<30} {str(inspect.signature(f)):<24} {natija}")


print("\n=== 2. lambda ≡ def ===")


def def_versiya(x):
    return x ** 2


lambda_versiya = lambda x: x ** 2

print(f"  def f(x): return x ** 2")
print(f"  g = lambda x: x ** 2\n")

TAQQOSLASH = [
    ("type", type(def_versiya).__name__, type(lambda_versiya).__name__),
    ("__name__", def_versiya.__name__, lambda_versiya.__name__),
    ("__doc__", str(def_versiya.__doc__), str(lambda_versiya.__doc__)),
    ("co_argcount", def_versiya.__code__.co_argcount,
     lambda_versiya.__code__.co_argcount),
    ("natija(5)", def_versiya(5), lambda_versiya(5)),
]

print(f"  {'Xususiyat':<16} {'def':<16} {'lambda'}")
print("  " + "─" * 46)
for nom, a, b in TAQQOSLASH:
    print(f"  {nom:<16} {str(a):<16} {b}")

print(f"\n  Bytecode bir xilmi: "
      f"{def_versiya.__code__.co_code == lambda_versiya.__code__.co_code}")

print(f"\n  def_versiya:")
dis.dis(def_versiya)
print(f"  lambda_versiya:")
dis.dis(lambda_versiya)


print("\n=== 3. ⚠️ Cheklovlar ===")

CHEKLOVLAR = [
    ("return",          "lambda x: return x"),
    ("O'zlashtirish",   "lambda x: y = x"),
    ("if buyrug'i",     "lambda x: if x: pass"),
    ("for buyrug'i",    "lambda x: for i in x: pass"),
    ("raise",           "lambda: raise ValueError"),
    ("pass",            "lambda: pass"),
    ("global",          "lambda: global x"),
    ("import",          "lambda: import os"),
    ("Bir necha buyruq", "lambda x: x + 1; x + 2"),
    ("Tur ko'rsatkichi", "lambda x: int -> int"),
]

print(f"  {'Cheklov':<20} {'Natija'}")
print("  " + "─" * 52)
for nom, kod in CHEKLOVLAR:
    try:
        eval(kod)
        natija = "✅ ishladi"
    except SyntaxError as e:
        natija = f"❌ SyntaxError: {e.msg}"
    except Exception as e:
        natija = f"❌ {type(e).__name__}"
    print(f"  {nom:<20} {natija}")


print("\n=== 4. ✅ Nima MUMKIN ===")

MUMKIN = [
    ("Shartli ifoda",       "lambda x: 'musbat' if x > 0 else 'manfiy'", (5,)),
    ("Ichma-ich shartli",   "lambda x: 'a' if x > 10 else 'b' if x > 5 else 'c'", (7,)),
    ("Generator",           "lambda n: [i ** 2 for i in range(n)]", (4,)),
    ("Lug'at generatori",   "lambda n: {i: i ** 2 for i in range(n)}", (3,)),
    ("Tuple",               "lambda x: (x, x ** 2, x ** 3)", (2,)),
    ("Funksiya chaqirish",  "lambda x: len(str(abs(x)))", (-1234,)),
    ("Walrus",              "lambda x: [(y := x * 2), y + 1]", (5,)),
    ("Ichma-ich lambda",    "lambda x: (lambda y: x + y)", (10,)),
    ("and/or",              "lambda x: x or 'sukut'", ("",)),
    ("Metod chaqirish",     "lambda s: s.strip().upper()", ("  ab  ",)),
]

print(f"  {'Shakl':<22} {'Kod':<48} {'Natija'}")
print("  " + "─" * 92)
for nom, kod, args in MUMKIN:
    f = eval(kod)
    natija = f(*args)
    if callable(natija):
        natija = f"<funksiya> → {natija(5)}"
    print(f"  {nom:<22} {kod[:46]:<48} {natija}")


print("\n=== 5. ⚠️ Hiylalar (ISHLATMANG) ===")

print(f"  raise hiylasi:")
xato_lambda = lambda: (_ for _ in ()).throw(ValueError("xato"))
try:
    xato_lambda()
except ValueError as e:
    print(f"    lambda: (_ for _ in ()).throw(ValueError('xato'))")
    print(f"    → ❌ ValueError: {e}")

print(f"\n  Bir necha 'buyruq' (tuple orqali):")
kop_amal = lambda x: (print(f"      chiqarildi: {x}"), x * 2)[1]
natija = kop_amal(5)
print(f"    lambda x: (print(x), x * 2)[1]  →  {natija}")

print(f"\n  exec hiylasi:")
print(f"    lambda: exec('x = 1')       ⚠️ ishlaydi, lekin QILMANG")

print("""
  ⚠️ Bu hiylalar TEXNIK jihatdan ishlaydi, lekin:
     • O'qib bo'lmaydi
     • Debug qiyin
     • Kod ko'rigida rad etiladi

  ⭐ Ko'p buyruq kerak bo'lsa — def yozing.
""")


print("\n=== 6. PEP 8 E731 ===")

print(f"  ❌ E731: do not assign a lambda expression, use a def\n")
print(f"    kvadrat = lambda x: x ** 2\n")
print(f"  ✅ To'g'ri:\n")
print(f"""    def kvadrat(x: int) -> int:
        \"\"\"Sonning kvadratini qaytaradi.\"\"\"
        return x ** 2
""")

print(f"  Sabablari:\n")

kvadrat_lambda = lambda x: x ** 2


def kvadrat_def(x: int) -> int:
    """Sonning kvadratini qaytaradi."""
    return x ** 2


FARQLAR = [
    ("__name__",        kvadrat_lambda.__name__, kvadrat_def.__name__),
    ("__doc__",         str(kvadrat_lambda.__doc__)[:20],
     str(kvadrat_def.__doc__)[:20]),
    ("Tur ko'rsatkichi", str(kvadrat_lambda.__annotations__),
     str(kvadrat_def.__annotations__)),
]

print(f"    {'Xususiyat':<20} {'lambda':<24} {'def'}")
print("    " + "─" * 62)
for nom, a, b in FARQLAR:
    print(f"    {nom:<20} {a:<24} {b}")

print(f"\n  Traceback da:")
xato_l = lambda x: 1 / x


def xato_d(x):
    return 1 / x


for f, nom in [(xato_l, "lambda"), (xato_d, "def")]:
    try:
        f(0)
    except ZeroDivisionError:
        import traceback
        # ⚠️ 3.11+ da oxiridan ikkinchi qator ~~^~~ belgilari bo'lishi mumkin,
        #    shuning uchun "File ..." bilan boshlanadigan OXIRGI qatorni olamiz
        fayl_qatorlari = [q.strip() for q in traceback.format_exc().splitlines()
                          if q.strip().startswith("File ")]
        qator = fayl_qatorlari[-1].split(", ", 1)[1]    # "line N, in nom"
        print(f"    {nom:<10} {qator}")

print(f"\n  ⭐ def bilan funksiya NOMI ko'rinadi — debug oson")

Natijaning muhim qismi:

text
=== 2. lambda ≡ def ===
  Xususiyat        def              lambda
  ──────────────────────────────────────────────
  type             function         function
  __name__         def_versiya      <lambda>
  __doc__          None             None
  natija(5)        25               25

  Bytecode bir xilmi: True

=== 3. ⚠️ Cheklovlar ===
  Cheklov              Natija
  ────────────────────────────────────────────────────
  return               ❌ SyntaxError: invalid syntax
  O'zlashtirish        ❌ SyntaxError: invalid syntax
  if buyrug'i          ❌ SyntaxError: invalid syntax
  raise                ❌ SyntaxError: invalid syntax

=== 6. PEP 8 E731 ===
  Traceback da:
    lambda     line 184, in <lambda>
    def        line 188, in xato_d

Nima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.

Misol 2 — key= va operator

python
"""lambda ning asosiy qo'llanishi va tezroq muqobillar."""

import timeit
from operator import itemgetter, attrgetter, methodcaller, neg
from dataclasses import dataclass

print("=== 1. key= funksiyasi ===")


@dataclass
class Xodim:
    ism: str
    yosh: int
    bolim: str
    maosh: int


XODIMLAR = [
    Xodim("Aziz", 30, "IT", 7_000_000),
    Xodim("Bobur", 25, "HR", 5_000_000),
    Xodim("Aziza", 35, "IT", 8_500_000),
    Xodim("Dilnoza", 28, "Moliya", 6_000_000),
]

SARALASHLAR = [
    ("Maosh bo'yicha",
     lambda x: x.maosh),
    ("Yosh bo'yicha (kamayish)",
     lambda x: -x.yosh),
    ("Bo'lim, keyin maosh↓",
     lambda x: (x.bolim, -x.maosh)),
    ("Ism uzunligi",
     lambda x: len(x.ism)),
    ("Ismning oxirgi harfi",
     lambda x: x.ism[-1]),
]

for nom, kalit in SARALASHLAR:
    natija = sorted(XODIMLAR, key=kalit)
    print(f"  {nom}:")
    print(f"    {[x.ism for x in natija]}")

print(f"\n  max/min bilan:")
print(f"    Eng katta maosh: {max(XODIMLAR, key=lambda x: x.maosh).ism}")
print(f"    Eng yosh:        {min(XODIMLAR, key=lambda x: x.yosh).ism}")
print(f"    Eng uzun ism:    {max(XODIMLAR, key=lambda x: len(x.ism)).ism}")


print("\n=== 2. ⭐ operator moduli ===")

TAQQOSLASH = [
    ("lambda x: x[1]",              "itemgetter(1)"),
    ("lambda x: (x[0], x[2])",      "itemgetter(0, 2)"),
    ("lambda x: x.maosh",           "attrgetter('maosh')"),
    ("lambda x: (x.bolim, x.maosh)", "attrgetter('bolim', 'maosh')"),
    ("lambda x: x.a.b",             "attrgetter('a.b')"),
    ("lambda s: s.upper()",         "methodcaller('upper')"),
    ("lambda s: s.count('a')",      "methodcaller('count', 'a')"),
    ("lambda a, b: a + b",          "operator.add"),
    ("lambda x: -x",                "operator.neg"),
    ("lambda a, b: a < b",          "operator.lt"),
    ("lambda x: len(x)",            "len  ⭐"),
    ("lambda x: str(x)",            "str  ⭐"),
    ("lambda x: int(x)",            "int  ⭐"),
]

print(f"  {'lambda':<34} {'Muqobil'}")
print("  " + "─" * 62)
for l, m in TAQQOSLASH:
    print(f"  {l:<34} {m}")


print("\n=== 3. Tezlik ===")

import random
random.seed(1)
MALUMOT = [(random.randrange(1000), random.randrange(1000))
           for _ in range(10_000)]
XODIMLAR_KOP = [Xodim(f"x{i}", i % 60, "IT", i * 1000) for i in range(10_000)]

SOZLASH = """
from operator import itemgetter, attrgetter
from __main__ import MALUMOT, XODIMLAR_KOP
"""

SINOVLAR = [
    ("sorted(key=lambda x: x[1])",      "sorted(MALUMOT, key=lambda x: x[1])"),
    ("sorted(key=itemgetter(1))",       "sorted(MALUMOT, key=itemgetter(1))"),
    ("sorted(key=lambda x: x.maosh)",   "sorted(XODIMLAR_KOP, key=lambda x: x.maosh)"),
    ("sorted(key=attrgetter('maosh'))", "sorted(XODIMLAR_KOP, key=attrgetter('maosh'))"),
]

natijalar = []
for nom, kod in SINOVLAR:
    vaqt = timeit.timeit(kod, setup=SOZLASH, number=100)
    natijalar.append((nom, vaqt))

print(f"  10 000 element × 100 marta:\n")
print(f"  {'Usul':<36} {'Vaqt':>9} {'Nisbat':>9}")
print("  " + "─" * 58)
for i in range(0, len(natijalar), 2):
    juftlik = natijalar[i:i + 2]
    eng_tez = min(v for _, v in juftlik)
    for nom, vaqt in juftlik:
        print(f"  {nom:<36} {vaqt:>7.3f} s {vaqt / eng_tez:>8.2f}x")
    print()

print(f"  ⭐ operator ~20-30% tezroq (C da yozilgan, freym yaratilmaydi)")


print("\n=== 4. O'qilish — qaysi biri yaxshi ===")

MISOLLAR = [
    ("key=len",                     "✅", "eng qisqa va aniq"),
    ("key=lambda x: len(x)",        "❌", "ortiqcha o'rash"),
    ("key=str.lower",               "✅", "tayyor metod"),
    ("key=lambda s: s.lower()",     "⚠️", "ishlaydi, lekin str.lower yaxshiroq"),
    ("key=attrgetter('maosh')",     "✅", "aniq"),
    ("key=lambda x: x.maosh",       "✅", "ham aniq, ba'zilar afzal ko'radi"),
    ("key=itemgetter(1)",           "⚠️", "1 nima? kontekstga bog'liq"),
    ("key=lambda x: x[1]",          "⚠️", "ham noaniq"),
    ("key=lambda kv: kv[1]",        "✅", "nom ma'no beradi"),
    ("key=lambda x: (x.a, -x.b)",   "✅", "ko'p mezon — lambda kerak"),
    ("key=itemgetter('bolim', 'maosh')", "✅", "nomli kalitlar — aniq"),
]

print(f"  {'Ifoda':<38} {'':<4} Izoh")
print("  " + "─" * 74)
for ifoda, belgi, izoh in MISOLLAR:
    print(f"  {ifoda:<38} {belgi:<4} {izoh}")

print("""
  ⭐ Qoida:
     • Tayyor funksiya bor         → uni ishlating (len, str.lower)
     • Atribut yoki nomli kalit    → attrgetter / itemgetter yoki lambda
     • Raqamli indeks              → nomli lambda o'qilishi yaxshiroq
     • Ko'p mezon / hisoblash      → lambda
""")


print("\n=== 5. Ko'p mezonli saralash ===")

print(f"  Bo'lim ↑, maosh ↓, ism ↑:\n")

USULLAR = [
    ("lambda (tuple + minus)",
     sorted(XODIMLAR, key=lambda x: (x.bolim, -x.maosh, x.ism))),
    ("Ketma-ket (barqarorlik)",
     None),
]

# Ketma-ket saralash
nusxa = list(XODIMLAR)
nusxa.sort(key=attrgetter("ism"))
nusxa.sort(key=attrgetter("maosh"), reverse=True)
nusxa.sort(key=attrgetter("bolim"))
USULLAR[1] = ("Ketma-ket (barqarorlik)", nusxa)

for nom, natija in USULLAR:
    print(f"  {nom}:")
    for x in natija:
        print(f"    {x.bolim:<8} {x.ism:<10} {x.maosh:>10,}")
    print()

print(f"  Bir xilmi: {USULLAR[0][1] == USULLAR[1][1]}")

print("""
  ⭐ lambda bilan tuple kalit — bir o'tishda
     Ketma-ket — turli yo'nalish kerak bo'lganda (6.3-dars)
""")


print("\n=== 6. Boshqa qo'llanishlar ===")

from collections import defaultdict
from itertools import groupby

print(f"  defaultdict:")
ikki_daraja = defaultdict(lambda: defaultdict(int))
ikki_daraja["IT"]["Aziz"] += 100
vektor = defaultdict(lambda: [0, 0, 0])
vektor["a"][1] = 5
print(f"    defaultdict(lambda: defaultdict(int)) → {dict(ikki_daraja)}")
print(f"    defaultdict(lambda: [0,0,0])         → {dict(vektor)}")

print(f"\n  groupby:")
saralangan = sorted(XODIMLAR, key=attrgetter("bolim"))
for bolim, guruh in groupby(saralangan, key=attrgetter("bolim")):
    ismlar = [x.ism for x in guruh]
    print(f"    {bolim:<10} {ismlar}")

print(f"\n  Funksiyalar lug'ati:")
AMALLAR = {
    "+": lambda a, b: a + b,
    "-": lambda a, b: a - b,
    "*": lambda a, b: a * b,
    "/": lambda a, b: a / b if b else float("inf"),
    "**": lambda a, b: a ** b,
}
for belgi, f in AMALLAR.items():
    print(f"    10 {belgi:<3} 3 = {f(10, 3)}")

print(f"\n  Filtrlar:")
FILTRLAR = {
    "musbat": lambda x: x > 0,
    "juft": lambda x: x % 2 == 0,
    "katta": lambda x: abs(x) > 10,
}
SONLAR = [-15, -2, 0, 3, 8, 21]
print(f"    Sonlar: {SONLAR}")
for nom, f in FILTRLAR.items():
    print(f"    {nom:<10} {[x for x in SONLAR if f(x)]}")

Natijaning muhim qismi:

text
=== 3. Tezlik ===
  10 000 element × 100 marta:

  Usul                                     Vaqt    Nisbat
  ──────────────────────────────────────────────────────────
  sorted(key=lambda x: x[1])              0.842 s     1.31x
  sorted(key=itemgetter(1))               0.643 s     1.00x

  sorted(key=lambda x: x.maosh)           0.912 s     1.28x
  sorted(key=attrgetter('maosh'))         0.712 s     1.00x

=== 4. O'qilish — qaysi biri yaxshi ===
  Ifoda                                       Izoh
  ──────────────────────────────────────────────────────────────────────────
  key=len                                ✅   eng qisqa va aniq
  key=lambda x: len(x)                   ❌   ortiqcha o'rash
  key=itemgetter(1)                      ⚠️   1 nima? kontekstga bog'liq
  key=lambda x: (x.a, -x.b)              ✅   ko'p mezon — lambda kerak

Nima ko'rsatdi: 2.3, 2.4-bo'limlar.

Misol 3 — Yopilma va tuzoqlar

python
"""lambda bilan yopilma va kech bog'lanish."""

from functools import partial

print("=== 1. lambda yopilma yaratadi ===")


def kopaytiruvchi(n):
    return lambda x: x * n


ikkilash = kopaytiruvchi(2)
uchlash = kopaytiruvchi(3)

print(f"  def kopaytiruvchi(n):")
print(f"      return lambda x: x * n\n")
print(f"    {'x':>4} {'ikkilash':>10} {'uchlash':>10}")
print("    " + "─" * 28)
for x in [1, 5, 10]:
    print(f"    {x:>4} {ikkilash(x):>10} {uchlash(x):>10}")

print(f"\n  Yopilma tarkibi:")
for nom, f in [("ikkilash", ikkilash), ("uchlash", uchlash)]:
    print(f"    {nom:<10} freevars={f.__code__.co_freevars}, "
          f"qiymat={f.__closure__[0].cell_contents}")


print("\n=== 2. ⚠️ Kech bog'lanish ===")

yomon = [lambda: i for i in range(3)]
print(f"  [lambda: i for i in range(3)]")
print(f"    → {[f() for f in yomon]}   ⚠️ hammasi 2\n")

print(f"  ✅ Uch yechim:\n")

y1 = [lambda i=i: i for i in range(3)]
print(f"    1. Sukut argument:")
print(f"       [lambda i=i: i for i in range(3)]")
print(f"       → {[f() for f in y1]}")

y2 = [partial(lambda x: x, i) for i in range(3)]
print(f"\n    2. functools.partial:")
print(f"       [partial(lambda x: x, i) for i in range(3)]")
print(f"       → {[f() for f in y2]}")

y3 = [(lambda n: lambda: n)(i) for i in range(3)]
print(f"\n    3. Ikki qavat lambda:")
print(f"       [(lambda n: lambda: n)(i) for i in range(3)]")
print(f"       → {[f() for f in y3]}")

print(f"\n  Yopilma farqi:")
print(f"    Yomon:  freevars={yomon[0].__code__.co_freevars}  (i — umumiy)")
print(f"    Sukut:  freevars={y1[0].__code__.co_freevars}  (i — parametr)")
print(f"    2 qavat: freevars={y3[0].__code__.co_freevars}, "
      f"qiymat={y3[0].__closure__[0].cell_contents}")


print("\n=== 3. Siklda handler ===")

handlerlar_yomon = {}
for nom in ["saqla", "yukla", "ochir"]:
    handlerlar_yomon[nom] = lambda: f"{nom} bajarildi"

handlerlar_yaxshi = {}
for nom in ["saqla", "yukla", "ochir"]:
    handlerlar_yaxshi[nom] = lambda n=nom: f"{n} bajarildi"

print(f"  ❌ Sukut argumentsiz:")
for nom, f in handlerlar_yomon.items():
    print(f"    {nom:<10} → {f()}")

print(f"\n  ✅ Sukut argument bilan:")
for nom, f in handlerlar_yaxshi.items():
    print(f"    {nom:<10} → {f()}")


print("\n=== 4. Funksiya fabrikasi ===")


def validator_yarat(min_q=None, max_q=None):
    """lambda bilan validator."""
    return lambda x: (
        (min_q is None or x >= min_q) and
        (max_q is None or x <= max_q)
    )


def validator_def(min_q=None, max_q=None):
    """def bilan — aniqroq."""

    def tekshir(x):
        if min_q is not None and x < min_q:
            return False
        if max_q is not None and x > max_q:
            return False
        return True

    qismlar = []
    if min_q is not None:
        qismlar.append(f">={min_q}")
    if max_q is not None:
        qismlar.append(f"<={max_q}")
    tekshir.__name__ = f"validator({', '.join(qismlar)})"
    tekshir.__doc__ = f"{min_q}..{max_q} oralig'ini tekshiradi"
    return tekshir


VALIDATORLAR = {
    "yosh": validator_def(0, 150),
    "ball": validator_def(0, 100),
    "maosh": validator_def(min_q=0),
}

print(f"  {'Maydon':<10} {'Validator nomi':<24} {'Sinovlar'}")
print("  " + "─" * 62)
for maydon, v in VALIDATORLAR.items():
    sinovlar = {q: v(q) for q in [-5, 50, 200]}
    print(f"  {maydon:<10} {v.__name__:<24} {sinovlar}")

print(f"\n  ⭐ def bilan __name__ va __doc__ berish mumkin — debug oson")


print("\n=== 5. Kompozitsiya ===")

kompozitsiya = lambda f, g: lambda x: f(g(x))


def kompozitsiya_def(*funksiyalar):
    """O'ngdan chapga: kompozitsiya(f, g)(x) == f(g(x))"""

    def natija(x):
        for f in reversed(funksiyalar):
            x = f(x)
        return x

    natija.__name__ = " ∘ ".join(f.__name__ for f in funksiyalar)
    return natija


ikkilash_f = lambda x: x * 2
qoshish_f = lambda x: x + 1
kvadrat_f = lambda x: x ** 2

zanjir_lambda = kompozitsiya(ikkilash_f, qoshish_f)
zanjir_def = kompozitsiya_def(str, abs, int)

print(f"  lambda bilan:")
print(f"    kompozitsiya(x*2, x+1)(5) = {zanjir_lambda(5)}   (2*(5+1))")

print(f"\n  def bilan (ko'p funksiya):")
print(f"    {zanjir_def.__name__}")
print(f"    zanjir('-42') = {zanjir_def('-42')!r}")

print(f"\n  Uch funksiya zanjiri:")
uch = kompozitsiya_def(kvadrat_f, ikkilash_f, qoshish_f)
print(f"    ((5+1)*2)² = {uch(5)}")

print("""
  ⚠️ Ko'p qavat lambda — o'qib bo'lmaydi:
     lambda f, g, h: lambda x: f(g(h(x)))

  ⭐ def yoki functools.reduce yaxshiroq.
""")


print("\n=== 6. ⚠️ Rekursiv lambda ===")

fakt = lambda n: 1 if n < 2 else n * fakt(n - 1)

print(f"  fakt = lambda n: 1 if n < 2 else n * fakt(n-1)")
print(f"    fakt(5) = {fakt(5)}   ✅ ishlaydi\n")

print(f"  ⚠️ Lekin global nomga bog'liq:")
asl_fakt = fakt
fakt = lambda n: -1
try:
    natija = asl_fakt(5)
    print(f"    fakt qayta bog'langandan keyin: asl_fakt(5) = {natija}   ⚠️ buzildi")
except RecursionError:
    print(f"    ❌ RecursionError")
fakt = asl_fakt

print(f"\n  ✅ def bilan — o'z nomiga bog'liq emas:")


def fakt_def(n):
    return 1 if n < 2 else n * fakt_def(n - 1)


nusxa = fakt_def
fakt_def = lambda n: -1
print(f"    nusxa(5) = {nusxa(5)}   ⚠️ ham buziladi")

print(f"\n  ✅ To'liq himoyalangan:")


def fakt_himoyalangan(n):
    def ichki(n):
        return 1 if n < 2 else n * ichki(n - 1)
    return ichki(n)


print(f"    fakt_himoyalangan(5) = {fakt_himoyalangan(5)}   ✅")

print("""
  ⚠️ Y-kombinator (nazariy mashq):

     Y = lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v)))
     fakt = Y(lambda f: lambda n: 1 if n < 2 else n * f(n-1))

  Bu — funksional dasturlash mashqi, amaliy kod EMAS.
""")

Y = lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v)))
fakt_y = Y(lambda f: lambda n: 1 if n < 2 else n * f(n - 1))
print(f"  Y-kombinator: fakt(5) = {fakt_y(5)}")


print("\n=== 7. ⚠️ O'zgaruvchan sukut ===")

yomon_lambda = lambda r=[]: (r.append(1), r)[1]

print(f"  f = lambda r=[]: (r.append(1), r)[1]\n")
for i in range(3):
    print(f"    f() → {yomon_lambda()}")

print(f"\n  ⚠️ lambda ham SUKUT QIYMAT tuzog'iga tushadi (7.3-dars)")

yaxshi_lambda = lambda r=None: [1] if r is None else [*r, 1]
print(f"\n  ✅ f = lambda r=None: [1] if r is None else [*r, 1]")
for i in range(3):
    print(f"    f() → {yaxshi_lambda()}")

Natijaning muhim qismi:

text
=== 2. ⚠️ Kech bog'lanish ===
  [lambda: i for i in range(3)]
    → [2, 2, 2]   ⚠️ hammasi 2

  ✅ Uch yechim:
    1. Sukut argument:
       → [0, 1, 2]
    2. functools.partial:
       → [0, 1, 2]
    3. Ikki qavat lambda:
       → [0, 1, 2]

=== 6. ⚠️ Rekursiv lambda ===
    fakt(5) = 120   ✅ ishlaydi

  ⚠️ Lekin global nomga bog'liq:
    fakt qayta bog'langandan keyin: asl_fakt(5) = -5   ⚠️ buzildi

=== 7. ⚠️ O'zgaruvchan sukut ===
    f() → [1]
    f() → [1, 1]
    f() → [1, 1, 1]

Nima ko'rsatdi: 2.5, 2.7-bo'limlar.

Misol 4 — Amaliy: so'rov qurish tizimi

python
"""lambda ning to'g'ri va noto'g'ri qo'llanishi — real vazifa."""

from dataclasses import dataclass
from operator import attrgetter, itemgetter
from typing import Callable, Any
from enum import Enum

print("=== Ma'lumot so'rovi tizimi ===\n")


@dataclass
class Buyurtma:
    id: int
    mijoz: str
    shahar: str
    summa: int
    holat: str
    sana: str


BUYURTMALAR = [
    Buyurtma(1, "Aziz", "Toshkent", 1_200_000, "yakunlangan", "2026-09-01"),
    Buyurtma(2, "Bobur", "Samarqand", 850_000, "jarayonda", "2026-09-03"),
    Buyurtma(3, "Aziza", "Toshkent", 2_100_000, "yakunlangan", "2026-09-05"),
    Buyurtma(4, "Dilnoza", "Buxoro", 450_000, "bekor", "2026-09-02"),
    Buyurtma(5, "Aziz", "Toshkent", 3_200_000, "jarayonda", "2026-09-07"),
    Buyurtma(6, "Eldor", "Samarqand", 1_800_000, "yakunlangan", "2026-09-04"),
]


class Sorov:
    """Zanjirlanadigan so'rov quruvchi."""

    def __init__(self, malumot: list, tarix: list | None = None):
        self._malumot = list(malumot)
        self._tarix = tarix or []

    def filtrla(self, shart: Callable[[Any], bool], izoh: str = "") -> "Sorov":
        """⭐ lambda TO'G'RI qo'llanishi — bir martalik shart."""
        return Sorov(
            [x for x in self._malumot if shart(x)],
            [*self._tarix, f"filtrla({izoh or '...'})"],
        )

    def sarala(self, kalit: Callable, teskari: bool = False,
               izoh: str = "") -> "Sorov":
        return Sorov(
            sorted(self._malumot, key=kalit, reverse=teskari),
            [*self._tarix, f"sarala({izoh or '...'}{', ↓' if teskari else ''})"],
        )

    def xarita(self, f: Callable, izoh: str = "") -> "Sorov":
        return Sorov(
            [f(x) for x in self._malumot],
            [*self._tarix, f"xarita({izoh or '...'})"],
        )

    def guruhla(self, kalit: Callable, izoh: str = "") -> dict:
        natija: dict = {}
        for x in self._malumot:
            natija.setdefault(kalit(x), []).append(x)
        return natija

    def chegarala(self, n: int) -> "Sorov":
        return Sorov(self._malumot[:n], [*self._tarix, f"chegarala({n})"])

    @property
    def natija(self) -> list:
        return self._malumot

    def __len__(self):
        return len(self._malumot)

    def hisobot(self, maydon: Callable = attrgetter("id")) -> str:
        qatorlar = [f"  Quvur: {' → '.join(self._tarix) or '(bo`sh)'}"]
        qatorlar.append(f"  Natija ({len(self._malumot)}): "
                        f"{[maydon(x) for x in self._malumot]}")
        return "\n".join(qatorlar)


print("=== 1. Zanjirlangan so'rov ===\n")

natija = (
    Sorov(BUYURTMALAR)
    .filtrla(lambda b: b.holat != "bekor", "bekor emas")
    .filtrla(lambda b: b.summa > 800_000, "summa > 800k")
    .sarala(attrgetter("summa"), teskari=True, izoh="summa")
    .chegarala(3)
)

print(natija.hisobot(attrgetter("mijoz")))

print(f"\n  Batafsil:")
print(f"    {'ID':>3} {'Mijoz':<10} {'Shahar':<12} {'Summa':>12} {'Holat'}")
print("    " + "─" * 54)
for b in natija.natija:
    print(f"    {b.id:>3} {b.mijoz:<10} {b.shahar:<12} "
          f"{b.summa:>12,} {b.holat}")


print("\n\n=== 2. ⭐ lambda vs operator ===\n")

MISOLLAR = [
    ("Bitta atribut",
     "sarala(lambda b: b.summa)",
     "sarala(attrgetter('summa'))",
     "⚠️ ikkalasi ham yaxshi"),
    ("Ko'p atribut",
     "sarala(lambda b: (b.shahar, b.summa))",
     "sarala(attrgetter('shahar', 'summa'))",
     "✅ attrgetter tezroq"),
    ("Teskari tartib",
     "sarala(lambda b: -b.summa)",
     "sarala(attrgetter('summa'), teskari=True)",
     "✅ teskari= aniqroq"),
    ("Hisoblash bilan",
     "sarala(lambda b: b.summa / len(b.mijoz))",
     "(muqobil yo'q)",
     "✅ lambda KERAK"),
    ("Aralash yo'nalish",
     "sarala(lambda b: (b.shahar, -b.summa))",
     "(ketma-ket saralash)",
     "✅ lambda qulayroq"),
]

print(f"  {'Holat':<20} {'Tavsiya'}")
print("  " + "─" * 68)
for holat, l, o, tavsiya in MISOLLAR:
    print(f"  {holat:<20} {tavsiya}")
    print(f"    lambda:   {l}")
    print(f"    operator: {o}\n")


print("=== 3. Guruhlash ===\n")

GURUHLASHLAR = [
    ("Shahar bo'yicha", attrgetter("shahar")),
    ("Holat bo'yicha", attrgetter("holat")),
    ("Summa toifasi", lambda b: (
        "katta" if b.summa > 2_000_000
        else "o'rta" if b.summa > 1_000_000
        else "kichik"
    )),
    ("Oy bo'yicha", lambda b: b.sana[:7]),
]

for nom, kalit in GURUHLASHLAR:
    guruhlar = Sorov(BUYURTMALAR).guruhla(kalit)
    print(f"  {nom}:")
    for k in sorted(guruhlar, key=str):
        buyurtmalar = guruhlar[k]
        jami = sum(b.summa for b in buyurtmalar)
        print(f"    {str(k):<14} {len(buyurtmalar)} ta, jami {jami:>12,}")
    print()


print("=== 4. Filtrlar registri ===\n")

FILTRLAR: dict[str, Callable[[Buyurtma], bool]] = {
    "yakunlangan": lambda b: b.holat == "yakunlangan",
    "jarayonda": lambda b: b.holat == "jarayonda",
    "katta": lambda b: b.summa > 1_500_000,
    "toshkent": lambda b: b.shahar == "Toshkent",
    "sentyabr": lambda b: b.sana.startswith("2026-09"),
}


def filtrlarni_qoll(malumot, *nomlar, rejim="and"):
    """Bir necha filtrni birlashtiradi."""
    if not nomlar:
        return list(malumot)
    shartlar = [FILTRLAR[n] for n in nomlar]
    if rejim == "and":
        return [x for x in malumot if all(s(x) for s in shartlar)]
    return [x for x in malumot if any(s(x) for s in shartlar)]


SOROVLAR = [
    (("yakunlangan",), "and"),
    (("yakunlangan", "toshkent"), "and"),
    (("katta", "toshkent"), "and"),
    (("jarayonda", "katta"), "or"),
]

print(f"  {'Filtrlar':<32} {'Rejim':<6} {'Natija'}")
print("  " + "─" * 60)
for nomlar, rejim in SOROVLAR:
    natija = filtrlarni_qoll(BUYURTMALAR, *nomlar, rejim=rejim)
    idlar = [b.id for b in natija]
    print(f"  {str(list(nomlar)):<32} {rejim:<6} {idlar}")

print("""
  ⭐ Filtrlar lug'ati — lambda ning yaxshi qo'llanishi:
     • Har biri bir qatorli
     • Nom ma'no beradi
     • Dinamik birlashtirish mumkin
""")


print("\n=== 5. ❌ lambda suiiste'moli ===\n")

print("""  Bu misolda lambda NOTO'G'RI ishlatilgan bo'lardi:

  1. Nomga bog'lash:
     ❌ jami_hisobla = lambda bs: sum(b.summa for b in bs)
     ✅ def jami_hisobla(bs: list[Buyurtma]) -> int:
            \"\"\"Buyurtmalar jami summasini hisoblaydi.\"\"\"
            return sum(b.summa for b in bs)

  2. Murakkab mantiq:
     ❌ toifa = lambda b: ("VIP" if b.summa > 3_000_000 and
                           b.holat == "yakunlangan" else
                           "oddiy" if b.summa > 1_000_000 else "kichik")
     ✅ def toifa(b: Buyurtma) -> str:
            if b.summa > 3_000_000 and b.holat == "yakunlangan":
                return "VIP"
            if b.summa > 1_000_000:
                return "oddiy"
            return "kichik"

  3. Yon ta'sir:
     ❌ list(map(lambda b: print(b.id), buyurtmalar))
     ✅ for b in buyurtmalar: print(b.id)

  4. Ortiqcha o'rash:
     ❌ sorted(bs, key=lambda b: attrgetter('summa')(b))
     ✅ sorted(bs, key=attrgetter('summa'))

  5. map/filter o'rniga generator:
     ❌ list(map(lambda b: b.summa, filter(lambda b: b.summa > 0, bs)))
     ✅ [b.summa for b in bs if b.summa > 0]
""")


print("=== 6. Yakuniy qoidalar ===\n")

print("""
  ┌──────────────────────────────────┬─────────────────────────────┐
  │ Holat                            │ Tanlov                      │
  ├──────────────────────────────────┼─────────────────────────────┤
  │ key=, bir martalik shart         │ lambda ⭐                    │
  │ Tayyor funksiya bor              │ len, str.lower, int         │
  │ Atribut / element olish          │ attrgetter / itemgetter     │
  │ Metod chaqirish                  │ methodcaller                │
  │ Ko'p mezon, hisoblash            │ lambda ⭐                    │
  │ Nomga bog'lash kerak             │ def (PEP 8 E731)            │
  │ Docstring / tur ko'rsatkichi     │ def                         │
  │ 2+ qator mantiq                  │ def                         │
  │ Yon ta'sir                       │ def yoki oddiy sikl         │
  │ Rekursiya                        │ def                         │
  │ map/filter + lambda              │ Generator ifodasi ⭐         │
  └──────────────────────────────────┴─────────────────────────────┘

  ⭐ Bir jumla: lambda — ARGUMENT sifatida uzatiladigan
     bir qatorli funksiya uchun. Boshqa hamma holatda — def.
""")

Natijaning muhim qismi:

text
=== 1. Zanjirlangan so'rov ===

  Quvur: filtrla(bekor emas) → filtrla(summa > 800k) → sarala(summa, ↓)
         → chegarala(3)
  Natija (3): ['Aziz', 'Aziza', 'Eldor']

  Batafsil:
     ID Mijoz      Shahar              Summa Holat
    ──────────────────────────────────────────────────────
      5 Aziz       Toshkent        3,200,000 jarayonda
      3 Aziza      Toshkent        2,100,000 yakunlangan
      6 Eldor      Samarqand       1,800,000 yakunlangan

=== 4. Filtrlar registri ===
  Filtrlar                         Rejim  Natija
  ────────────────────────────────────────────────────────────
  ['yakunlangan']                  and    [1, 3, 6]
  ['yakunlangan', 'toshkent']      and    [1, 3]
  ['jarayonda', 'katta']           or     [2, 3, 5, 6]

Nima ko'rsatdi: 2.3, 2.4-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"lambda def dan tezroq" Bytecode bir xil
"lambda — maxsus tur" Oddiy function obyekti
"lambda da return kerak" Ifoda avtomatik qaytariladi
"lambda ko'p qatorli bo'la oladi" Texnik ha, lekin def yozing
"f = lambda x: ... — normal" PEP 8 E731 — def ishlating
"key=lambda x: len(x) yaxshi" key=len — soddaroq
"lambda yopilma yaratmaydi" Yaratadi — kech bog'lanish tuzog'i bilan
"lambda sukut argument tuzog'idan xoli" Bir xil tuzoq
"map(lambda...) generatordan yaxshi" Generator o'qilishi va tezligi yaxshiroq

6. Keng tarqalgan xatolar va yechimlari

1. Nomga bog'lash (E731)

python
kvadrat = lambda x: x ** 2          # ❌
def kvadrat(x): return x ** 2       # ✅

2. Ortiqcha o'rash

python
key=lambda x: len(x)                # ❌
key=len                             # ✅

key=lambda s: s.lower()             # ⚠️
key=str.lower                       # ✅

3. Kech bog'lanish

python
[lambda: i for i in range(3)]       # ⚠️ [2,2,2]
[lambda i=i: i for i in range(3)]   # ✅

4. Murakkab mantiq

python
lambda x: a if p(x) else b if q(x) else c       # ❌
# → def yozing

5. Yon ta'sir

python
list(map(lambda x: print(x), r))    # ❌
for x in r: print(x)                # ✅

6. O'zgaruvchan sukut

python
lambda r=[]: r.append(1)            # ⚠️ tuzoq
lambda r=None: [*(r or []), 1]      # ✅

7. map/filter + lambda

python
list(map(lambda x: x*2, r))         # ❌
[x * 2 for x in r]                  # ✅

8. Rekursiv lambda

python
fakt = lambda n: 1 if n<2 else n*fakt(n-1)      # ⚠️ global nomga bog'liq
def fakt(n): ...                                 # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 7.1-dars (o'tilgan): funksiya — obyekt
  • 7.8-dars (o'tilgan): yopilma, kech bog'lanish
  • 6.3-dars (o'tilgan): key= bilan saralash
  • 7.11-dars: funksiya — birinchi darajali obyekt
  • 7.12-dars: map, filter, reduce
  • 10, 15-qismlar: funksional dasturlash, functools, operator
  • PEP 8: E731 qoidasi

8. Eng yaxshi amaliyotlar

  1. lambda — faqat argument sifatida. key=, callback, default_factory.

  2. Nomga bog'lash kerak bo'lsa — def. PEP 8 E731.

  3. Tayyor funksiya bor bo'lsa — uni ishlating. len, str.lower, int.

  4. Atribut/element uchun operator. attrgetter, itemgetter — tezroq.

  5. Siklda lambda — sukut argument bilan. Kech bog'lanish.

  6. Bir qatorga sig'masa — def. O'qilish qisqalikdan muhim.

  7. map/filter + lambda o'rniga generator. [x*2 for x in r].

  8. Yon ta'sir uchun lambda ishlatmang. Sikl yoki def.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
1.  print((lambda x: x ** 2)(5))
2.  print(type(lambda: 1))
3.  print((lambda: 1).__name__)
4.  f = lambda x, y=2: x ** y
    print(f(3), f(3, 3))
5.  print((lambda *a: sum(a))(1, 2, 3))
6.  print([f() for f in [lambda: i for i in range(3)]])
7.  print([f() for f in [lambda i=i: i for i in range(3)]])
8.  print(sorted(["bb", "a", "ccc"], key=lambda s: len(s)))
9.  print(sorted(["bb", "a", "ccc"], key=len))
10. f = lambda r=[]: (r.append(1), len(r))[1]
    print(f(), f(), f())
11. print((lambda x: x if x > 0 else -x)(-5))
12. g = lambda: (lambda: 42)
    print(g()())
Javoblar
  1. 25
  2. <class 'function'>
  3. <lambda>
  4. 9 27
  5. 6
  6. [2, 2, 2] — kech bog'lanish
  7. [0, 1, 2]
  8. ['a', 'bb', 'ccc']
  9. ['a', 'bb', 'ccc'] — bir xil, lekin soddaroq
  10. 1 2 3 — o'zgaruvchan sukut tuzog'i
  11. 5
  12. 42

Vazifa 2: Xatolarni tuzating

python
1.  kvadrat = lambda x: x ** 2
2.  sorted(r, key=lambda x: len(x))
3.  sorted(r, key=lambda x: x.maosh)   # tezroq kerak
4.  [lambda: i for i in range(3)]
5.  list(map(lambda x: x * 2, r))
6.  list(map(lambda x: print(x), r))
7.  f = lambda x: (a if p(x) else b if q(x) else c)
8.  f = lambda r=[]: r.append(1)
Javoblar
python
1.  def kvadrat(x: int) -> int: return x ** 2
2.  sorted(r, key=len)
3.  sorted(r, key=attrgetter("maosh"))
4.  [lambda i=i: i for i in range(3)]
5.  [x * 2 for x in r]
6.  for x in r: print(x)
7.  def f(x):
        if p(x): return a
        if q(x): return b
        return c
8.  def f(r=None): r = [] if r is None else r; r.append(1); return r

Vazifa 3: lambda → def refaktoringi

Berilgan lambda larni def ga o'tkazing va qaysi biri yaxshiroq — izohlang:

python
1.  kesim = lambda s, n: s[:n] + "…" if len(s) > n else s
2.  toifa = lambda b: "a" if b >= 90 else "b" if b >= 70 else "c"
3.  key = lambda x: (x.bolim, -x.maosh, x.ism)
4.  validator = lambda x: isinstance(x, int) and 0 <= x <= 150
5.  formatla = lambda n: f"{n:,}".replace(",", " ")
6.  kompozitsiya = lambda f, g: lambda x: f(g(x))

Vazifa 4: operator bilan almashtirish

Har bir lambda uchun operator muqobilini toping (yoki "yo'q" deb yozing):

python
1.  lambda x: x[0]
2.  lambda x: x[1:3]
3.  lambda x: x.ism
4.  lambda x: x.a.b.c
5.  lambda x: x.upper()
6.  lambda x: x.replace("a", "b")
7.  lambda a, b: a * b
8.  lambda x: not x
9.  lambda x: x in [1, 2, 3]
10. lambda x: len(x) > 5

Vazifa 5: Filtrlar tizimi

Yozing:

  1. FILTRLAR lug'ati (10+ filtr, lambda bilan)
  2. birlashtir(*nomlar, rejim) — AND/OR
  3. teskari(nom) — NOT
  4. qurish(ifoda) — "katta AND (toshkent OR samarqand)"
  5. Har filtr uchun __doc__ (def bilan)
  6. Tezlikni operator bilan solishtiring

Vazifa 6: lambda linteri

Vosita yozing (ast bilan):

  1. lambda nomga bog'langanini topsin (E731)
  2. Ortiqcha o'rashni (lambda x: f(x))
  3. Murakkab lambda (2+ shartli ifoda)
  4. Siklda sukut argumentsiz lambda
  5. map/filter + lambda
  6. Har biri uchun tuzatish taklifi

Vazifa 7: O'ylash

Nega Python lambda ni bitta ifoda bilan chekladi, boshqa tillar kabi ko'p qatorli anonim funksiyaga ruxsat bermadi?

Javob

Sabab: Pythonda blok chegarasi — otstup, va u ifoda ichida ishlamaydi.

Texnik muammo:

Pythonda blok otstup bilan belgilanadi:

python
def f():
    x = 1
    return x

Anonim funksiya ifoda — u boshqa ifoda ichida bo'lishi mumkin:

python
sorted(r, key=lambda x: ...)
d = {"a": lambda: ...}
f(lambda: ..., g(lambda: ...))

Ko'p qatorli bo'lsa, otstup qanday hisoblanadi?

python
sorted(r, key=lambda x:
    y = x * 2           # ⚠️ bu otstup nimaga nisbatan?
    return y            # ⚠️ va bu?
)

Grammatika noaniq bo'lardi. Ayniqsa ichma-ich:

python
f(lambda x:
    g(lambda y:
        ...             # ⚠️ qaysi lambda ga tegishli?
    )
)

Boshqa tillar qanday hal qilgan:

Qavs bilan (JavaScript, C#, Java):

javascript
arr.sort((a, b) => {
    const x = a * 2;
    return x - b;
});

Blok {} bilan belgilanadi — otstup ahamiyatsiz.

Ruby:

ruby
arr.sort do |a, b|
    x = a * 2
    x <=> b
end

do...end bloki.

Pythonda {} yo'q — bu tilning asosiy dizayn qarori. Uni faqat lambda uchun qo'shish izchil bo'lmasdi.

Guido ning pozitsiyasi:

Guido bir necha marta yozgan (2006, 2018):

"I think it's usually a bad idea to write large anonymous functions... The whole point of a lambda is that it's a small function."

Va:

"If you need multiple statements, you need a name. And if you have a name, use def."

Falsafiy dalil:

Agar funksiya bir necha qatordan iborat bo'lsa, u nom talab qiladi:

  • Nom uning maqsadini tushuntiradi
  • Traceback da ko'rinadi
  • Test qilish mumkin
  • Qayta ishlatiladi
  • Docstring bo'lishi mumkin
python
# Anonim, ko'p qatorli (tasavvur)
sorted(xodimlar, key=lambda x:
    ... 10 qator murakkab mantiq ...
)

# Nom bilan
def saralash_kaliti(xodim: Xodim) -> tuple:
    """Bo'lim, keyin maosh (kamayish), keyin ism bo'yicha."""
    ... 10 qator ...

sorted(xodimlar, key=saralash_kaliti)

Ikkinchisi har jihatdan yaxshiroq.

Takliflar bo'lganmi?

Ha, ko'p. Eng mashhurlari:

PEP 3113 (rad etilgan) — tuple parametrlarini olib tashlash bilan bog'liq.

Anonim blok takliflari (python-ideas, ko'p marta):

python
sorted(r, key=(x) => {
    ...
})

Har safar rad etilgan. Sabablar:

  1. Grammatika murakkablashadi
  2. {} Python sintaksisiga yot
  3. def allaqachon bor va yaxshiroq
  4. Ko'p qatorli lambda — kod hidi (code smell)

PEP 8 pozitsiyasi:

E731 qoidasi lambda ni nomga bog'lashni ham taqiqlaydi:

python
f = lambda x: 2 * x     # E731

Ya'ni: lambda faqat argument sifatida ishlatilishi kerak.

Amaliy natija:

Cheklov — xususiyat, kamchilik emas:

  • lambda kichik bo'lishga majbur qiladi
  • Murakkab mantiq nom oladi
  • Kod o'qilishi yaxshilanadi

Solishtiring:

JavaScript da ko'p qatorli anonim funksiya keng tarqalgan:

javascript
fetch(url).then(response => {
    if (!response.ok) {
        throw new Error("...");
    }
    return response.json();
}).then(data => {
    ... 20 qator ...
});

Bu — "callback hell" muammosining bir qismi. Python bunga yo'l bermaydi.

Xulosa: cheklov texnik (otstup grammatikasi) va falsafiy (kichik funksiyalar) sabablarning birikmasi. Amalda u kodni yaxshilaydi: agar lambda bir qatorga sig'masa, bu — def yozish vaqti kelganining belgisi.

Nimani mustahkamlaydi: 2.2, 2.3-bo'limlar.


Xulosa

Bu darsda lambda ni o'rgandik.

Eng muhim uch fikr:

  1. lambda — bitta ifodadan iborat anonim funksiya. def bilan bytecode bir xil — farq faqat sintaksisda va __name__ da. return, o'zlashtirish, if/for buyruqlari, docstring va tur ko'rsatkichlari yo'q.

  2. Asosiy qo'llanish — key= va bir martalik callback. sorted(r, key=lambda x: (x.bolim, -x.maosh)). Nomga bog'lash — PEP 8 E731 buzilishi: def docstring, tur ko'rsatkichlari va aniq traceback beradi.

  3. Tayyor funksiya bor bo'lsa — uni ishlating. key=len, key=str.lower, key=attrgetter("maosh") — qisqaroq va tezroq (operator C da yozilgan). Va siklda lambda — doim sukut argument bilan (lambda i=i: i).

Keyingi darsda funksiya — birinchi darajali obyekt mavzusini ko'ramiz: funksiyalarni saqlash, uzatish, qaytarish va yuqori tartibli funksiyalar.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
7.10-dars: lambda — anonim funksiya — IlmHamroh