Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Sintaksis
- 2.2. Ichma-ich generatorlar
- 2.3. Qamrov (scope)
- 2.4. Tezlik — nega generator tezroq
- 2.5. Qachon ISHLATMASLIK
- 2.6. Muqobil shakllar
- 2.7. Boshqa generator turlari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Sintaksis to'liq
- Misol 2 — Qamrov va tuzoqlar
- Misol 3 — Tezlik va muqobillar
- Misol 4 — Amaliy: ma'lumot qayta ishlash
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
6.15-dars: Ro'yxat generatori (list comprehension)
6-QISM — MA'LUMOT TUZILMALARI · 15-dars
1. Kirish va motivatsiya
Ro'yxat generatori — Pythonning eng tanilgan sintaksisi:
# Oddiy sikl
kvadratlar = []
for x in range(10):
kvadratlar.append(x ** 2)
# Generator
kvadratlar = [x ** 2 for x in range(10)]Bir qator o'rniga to'rt qator. Va u tezroq ham.
Lekin generator tez chalkash bo'lib ketadi:
# Bu nima qiladi?
natija = [y for x in matritsa for y in x if y > 0]
# Bu-chi?
[[f(x, y) for y in range(3)] for x in range(3)]
# Bu?
[x if x > 0 else 0 for x in sonlar] # ✅
[x for x in sonlar if x > 0 else 0] # ❌ SyntaxErrorVa nozik tuzoqlar bor:
funksiyalar = [lambda: i for i in range(3)]
[f() for f in funksiyalar] # [2, 2, 2] ← nega?!
x = 10
[x for x in range(3)]
print(x) # 10 — Python 3 da o'zgarmadi ✅Bu darsda:
- Sintaksis va bajarilish tartibi
iffiltri va shartli ifoda — farqi- Ichma-ich generatorlar va ularning tartibi
- Qamrov (scope) — Python 2 vs 3
- Tezlik — nega generator tezroq
- Qachon ishlatmaslik — o'qilish chegarasi
2. Nazariya — chuqur tushuntirish
2.1. Sintaksis
Asosiy shakl:
[IFODA for O'ZGARUVCHI in KETMA-KETLIK][x ** 2 for x in range(5)] # [0, 1, 4, 9, 16]
[s.upper() for s in ["a", "b"]] # ['A', 'B']
[len(s) for s in sozlar]Filtr bilan:
[IFODA for O'ZGARUVCHI in KETMA-KETLIK if SHART][x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
[s for s in sozlar if len(s) > 3] Bajarilish tartibi — chapdan o'ngga, for dan boshlab:
[IFODA for x in KETMA-KETLIK if SHART]
↑ ↑ ↑
3 1 2Ya'ni:
KETMA-KETLIKdan element olinadiSHARTtekshiriladi- Shart to'g'ri bo'lsa
IFODAhisoblanadi
Ekvivalent sikl:
natija = []
for x in KETMA_KETLIK:
if SHART:
natija.append(IFODA) if — filtr, if/else — ifoda:
[x for x in sonlar if x > 0] # ✅ FILTR — elementlar tushib qoladi
[x if x > 0 else 0 for x in sonlar] # ✅ IFODA — hamma element qoladi
[x for x in sonlar if x > 0 else 0] # ❌ SyntaxErrorFarq muhim:
sonlar = [-2, -1, 0, 1, 2]
[x for x in sonlar if x > 0] # [1, 2] — 2 element
[x if x > 0 else 0 for x in sonlar] # [0, 0, 0, 1, 2] — 5 elementIkkalasi birga:
[x * 2 if x > 0 else 0 for x in sonlar if x != 0]
# ↑ ifoda (if/else) ↑ filtr
# [0, 0, 2, 4]Bu — chegara. Bundan murakkabroq bo'lsa oddiy sikl yozing.
2.2. Ichma-ich generatorlar
Ikki for — tekislash:
matritsa = [[1, 2], [3, 4], [5, 6]]
[y for x in matritsa for y in x] # [1, 2, 3, 4, 5, 6]Tartib — sikl bilan bir xil, chapdan o'ngga:
[y for x in matritsa for y in x]
# ekvivalenti:
natija = []
for x in matritsa: # ← birinchi for
for y in x: # ← ikkinchi for
natija.append(y)Bu — eng ko'p chalkashtiradigan joy. Ko'pchilik teskarisini kutadi.
Eslash usuli: for lar sikldagi kabi tartibda yoziladi, faqat IFODA oldinga chiqadi.
Ichma-ich ro'yxat qurish — ikkita []:
[[f(x, y) for y in range(3)] for x in range(2)]
# ekvivalenti:
natija = []
for x in range(2):
qator = []
for y in range(3):
qator.append(f(x, y))
natija.append(qator)Solishtiring:
[y for x in m for y in x] # TEKIS ro'yxat
[[y for y in x] for x in m] # ICHMA-ICH ro'yxat (nusxa)Ikkinchi for birinchisiga bog'liq bo'lishi mumkin:
[(i, j) for i in range(3) for j in range(i)]
# [(1,0), (2,0), (2,1)]Har for dan keyin if:
[y for x in matritsa if len(x) > 1 for y in x if y > 2]
# ↑ birinchi filtr ↑ ikkinchi filtrEkvivalenti:
for x in matritsa:
if len(x) > 1:
for y in x:
if y > 2:
natija.append(y)2.3. Qamrov (scope)
Python 3 da generator o'zgaruvchisi tashqariga "sizmaydi":
x = 10
[x for x in range(3)]
print(x) # 10 ✅ o'zgarmadiPython 2 da sizardi:
# Python 2
x = 10
[x for x in range(3)]
print x # 2 ⚠️Bu — Python 3 ning muhim tuzatishlaridan biri.
Qanday ishlaydi: generator o'zining yashirin funksiya qamrovi ichida bajariladi:
# [x**2 for x in r] taxminan shunga teng:
def _yashirin(iterator):
natija = []
for x in iterator:
natija.append(x ** 2)
return natija
_yashirin(iter(r))Bir istisno — birinchi iterable tashqarida hisoblanadi:
[x for x in undefined_nom] # ❌ NameError darhol
[undefined_nom for x in range(3)] # ❌ NameError bajarilgandaSinf tanasi ichida — nozik holat:
class A:
qiymatlar = [1, 2, 3]
ikkilangan = [x * 2 for x in qiymatlar] # ✅ ishlaydi
yigindi = [x + y for x in qiymatlar for y in qiymatlar] # ❌ NameError!Sabab: birinchi for ning iterable'i tashqi qamrovda hisoblanadi (qiymatlar — sinf atributi, ko'rinadi), lekin generator tanasi ichida sinf qamrovi ko'rinmaydi.
Yechim:
class A:
qiymatlar = [1, 2, 3]
yigindi = [x + y for x in qiymatlar for y in A.qiymatlar] # ❌ A hali yo'qTo'g'ri yechim — generatorni sinfdan tashqarida yoki metod ichida yozish.
Kech bog'lanish (late binding) tuzog'i:
funksiyalar = [lambda: i for i in range(3)]
[f() for f in funksiyalar] # [2, 2, 2] ⚠️Sabab: lambda i ni hisoblamaydi, faqat unga havola saqlaydi. Sikl tugaganda i == 2.
Yechim — sukut argument:
funksiyalar = [lambda i=i: i for i in range(3)]
[f() for f in funksiyalar] # [0, 1, 2] ✅Yoki functools.partial:
from functools import partial
funksiyalar = [partial(lambda x: x, i) for i in range(3)]Bu — 7-qismda batafsil ko'riladi.
2.4. Tezlik — nega generator tezroq
import timeit
timeit.timeit("[x*2 for x in range(1000)]", number=10000) # ~0.35 s
timeit.timeit("""
natija = []
for x in range(1000):
natija.append(x*2)
""", number=10000) # ~0.62 s~1.8x tezroq. Sabablar:
1. append metod qidiruvi yo'q:
Sikldagi har iteratsiyada:
natijanomini qidirish.appendatributini qidirish- Metod obyektini yaratish
- Chaqirish
Generatorda — maxsus bytecode (LIST_APPEND), bularsiz.
2. Bytecode farqi:
import dis
dis.dis("[x*2 for x in r]")
# ...
# LIST_APPEND 2 ← C darajasidadis.dis("""
n = []
for x in r: n.append(x*2)
""")
# LOAD_NAME n
# LOAD_METHOD append ← har iteratsiyada
# ...
# CALL_METHOD 1
# POP_TOP3. Ro'yxat hajmi taxmin qilinadi:
Generator natija hajmini oldindan taxmin qiladi (kirish __len__ bo'lsa) va kamroq qayta ajratish qiladi.
Lekin funksiya chaqiruvi bo'lsa farq kamayadi:
[qimmat(x) for x in r] # farq ~5%
[x * 2 for x in r] # farq ~80%Chunki qimmat(x) vaqti append narxidan katta.
map bilan solishtirish:
[f(x) for x in r] # generator
list(map(f, r)) # mapmap biroz tezroq (funksiya to'g'ridan-to'g'ri chaqiriladi), lekin faqat tayyor funksiya bilan:
list(map(str.upper, sozlar)) # ✅ tezroq
list(map(lambda x: x * 2, r)) # ⚠️ sekinroq (lambda qo'shimcha)
[x * 2 for x in r] # ✅ eng tez2.5. Qachon ISHLATMASLIK
Generator — vosita, maqsad emas. U o'qilishni yaxshilaganda ishlatiladi.
1. Juda uzun yoki murakkab:
# ❌ O'qib bo'lmaydi
natija = [transform(x, y) for x in katta_royxat if shart1(x)
for y in x.elementlar if shart2(y) and shart3(x, y)]
# ✅ Oddiy sikl
natija = []
for x in katta_royxat:
if not shart1(x):
continue
for y in x.elementlar:
if shart2(y) and shart3(x, y):
natija.append(transform(x, y))Amaliy qoida: ikkitadan ko'p for/if bo'lsa — sikl.
2. Yon ta'sir uchun:
[print(x) for x in r] # ❌ ro'yxat keraksiz yaratiladi
for x in r: print(x) # ✅
[d.update({x: 1}) for x in r] # ❌
for x in r: d[x] = 1 # ✅Generator qiymat yaratish uchun. Yon ta'sir uchun — sikl.
3. Natija kerak bo'lmasa:
[f(x) for x in katta] # ⚠️ katta ro'yxat yaratiladi va tashlanadi
for x in katta: f(x) # ✅
any(f(x) for x in katta) # ✅ generator ifodasi (17-dars)4. Xotira muhim bo'lsa:
jami = sum([x ** 2 for x in range(10**7)]) # ⚠️ ~400 MB
jami = sum(x ** 2 for x in range(10**7)) # ✅ ~200 baytGenerator ifodasi (qavssiz) — 17-dars.
5. Murakkab shart mantiqisi:
# ❌
[qayta_ishla(x) if turi(x) == "a" else boshqa(x) if turi(x) == "b" else sukut(x)
for x in r]
# ✅ Funksiya ajrating
def qayta_ishla_bitta(x):
match turi(x):
case "a": return qayta_ishla(x)
case "b": return boshqa(x)
case _: return sukut(x)
[qayta_ishla_bitta(x) for x in r]2.6. Muqobil shakllar
map va filter:
[f(x) for x in r] ≡ list(map(f, r))
[x for x in r if p(x)] ≡ list(filter(p, r))
[f(x) for x in r if p(x)] ≡ list(map(f, filter(p, r)))Qaysi birini:
list(map(str.upper, sozlar)) # ✅ tayyor funksiya — map o'qiladi
[s.upper() for s in sozlar] # ✅ ham yaxshi
list(map(lambda s: s.upper(), sozlar)) # ⚠️ generator yaxshiroqQoida: lambda yozish kerak bo'lsa — generator.
itertools:
from itertools import chain, product, starmap
# Tekislash
[y for x in m for y in x] ≡ list(chain.from_iterable(m))
# Dekart ko'paytmasi
[(i, j) for i in a for j in b] ≡ list(product(a, b))
# Argumentlarni ochish
[f(*args) for args in juftliklar] ≡ list(starmap(f, juftliklar))numpy (katta sonli massivlar uchun):
[x ** 2 for x in katta_royxat] # ~O(n) Python darajasida
np.array(katta) ** 2 # ~50-100x tezroq2.7. Boshqa generator turlari
Ro'yxat generatori — to'rtta shakldan biri:
[x for x in r] # list
{x for x in r} # set (16-dars)
{k: v for k, v in r} # dict (16-dars)
(x for x in r) # generator (17-dars)Tuple generatori yo'q:
(x for x in r) # generator, tuple EMAS!
tuple(x for x in r) # ✅ tupleSabab: () generator ifodasi uchun band. Bu — 17-darsda.
3. Tez ma'lumotnoma
Sintaksis
[IFODA for X in KETMA-KETLIK]
[IFODA for X in KETMA-KETLIK if SHART]
[IFODA if A else B for X in KETMA-KETLIK] ⭐ ifoda
[IFODA for X in K1 for Y in K2] ichma-ich
Bajarilish: for → if → IFODA if filtri vs if/else ifodasi
[x for x in s if x > 0] FILTR — elementlar tushadi
[x if x > 0 else 0 for x in s] IFODA — hamma qoladi
[x for x in s if x > 0 else 0] ❌ SyntaxErrorIchma-ich tartib — sikldagi kabi
[y for x in m for y in x] TEKIS
↑ 3 ↑ 1 ↑ 2
for x in m: ← birinchi for
for y in x: ← ikkinchi for
natija.append(y)
[[y for y in x] for x in m] ICHMA-ICHQamrov
x = 10; [x for x in r]; print(x) → 10 ✅ Python 3
⚠️ Sinf tanasida ikkinchi `for` sinf atributini KO'RMAYDI
⚠️ [lambda: i for i in range(3)] → hammasi 2 (kech bog'lanish)
[lambda i=i: i for i in range(3)] ✅Qachon ISHLATMASLIK
> 2 ta for/if → oddiy sikl
Yon ta'sir ([print(x) ...]) → oddiy sikl
Natija kerak emas → sikl yoki generator ifodasi
Katta ma'lumot → (x for x in ...) 17-dars
Murakkab shart mantiqi → funksiya ajratingMuqobillar
list(map(f, r)) tayyor funksiya bilan
list(filter(p, r))
chain.from_iterable(m) tekislash
product(a, b) dekart ko'paytmasi
np.array(r) ** 2 sonli massiv — 50-100x4. Batafsil misollar
Misol 1 — Sintaksis to'liq
"""Ro'yxat generatorining barcha shakllari."""
import dis
print("=== 1. Asosiy shakllar ===")
SONLAR = [-3, -1, 0, 2, 4, 7]
SOZLAR = ["olma", "anor", "shaftoli", "uzum", "behi"]
NAMUNALAR = [
("[x**2 for x in range(5)]",
[x ** 2 for x in range(5)]),
("[s.upper() for s in SOZLAR]",
[s.upper() for s in SOZLAR]),
("[len(s) for s in SOZLAR]",
[len(s) for s in SOZLAR]),
("[x for x in SONLAR if x > 0]",
[x for x in SONLAR if x > 0]),
("[s for s in SOZLAR if len(s) > 4]",
[s for s in SOZLAR if len(s) > 4]),
("[x if x > 0 else 0 for x in SONLAR]",
[x if x > 0 else 0 for x in SONLAR]),
("[abs(x) for x in SONLAR if x != 0]",
[abs(x) for x in SONLAR if x != 0]),
]
for kod, natija in NAMUNALAR:
print(f" {kod:<40} → {natija}")
print("\n=== 2. ⚠️ if filtri vs if/else ifodasi ===")
print(f" SONLAR = {SONLAR}\n")
filtr = [x for x in SONLAR if x > 0]
ifoda = [x if x > 0 else 0 for x in SONLAR]
print(f" [x for x in s if x > 0] → {filtr}")
print(f" {len(filtr)} element (filtrlandi)")
print(f"\n [x if x > 0 else 0 for x in s] → {ifoda}")
print(f" {len(ifoda)} element (hammasi)")
print(f"\n ❌ [x for x in s if x > 0 else 0]:")
try:
eval("[x for x in SONLAR if x > 0 else 0]")
except SyntaxError as x:
print(f" SyntaxError: {x.msg}")
print(f"\n ✅ Ikkalasi birga:")
ikkalasi = [x * 10 if x > 0 else -1 for x in SONLAR if x != 0]
print(f" [x*10 if x > 0 else -1 for x in s if x != 0]")
print(f" → {ikkalasi}")
print(f" ⚠️ Bu — o'qish chegarasi. Murakkabroq bo'lsa sikl yozing.")
print("\n=== 3. Bajarilish tartibi ===")
kuzatuv = []
def manba():
for i in range(4):
kuzatuv.append(f"manba({i})")
yield i
def shart(x):
kuzatuv.append(f"shart({x})")
return x % 2 == 0
def ifoda(x):
kuzatuv.append(f"ifoda({x})")
return x * 10
natija = [ifoda(x) for x in manba() if shart(x)]
print(f" [ifoda(x) for x in manba() if shart(x)]\n")
print(f" Natija: {natija}\n")
print(f" Chaqiruvlar tartibi:")
for i, q in enumerate(kuzatuv, 1):
print(f" {i:>2}. {q}")
print("""
⭐ Har element uchun: manba → shart → (to'g'ri bo'lsa) ifoda
Ya'ni: for → if → IFODA
""")
print("\n=== 4. Ichma-ich generatorlar ===")
MATRITSA = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
print(f" MATRITSA = {MATRITSA}\n")
tekis = [y for x in MATRITSA for y in x]
ichma_ich = [[y for y in x] for x in MATRITSA]
ikkilangan = [[y * 2 for y in x] for x in MATRITSA]
print(f" [y for x in m for y in x] → {tekis}")
print(f" ⭐ TEKIS")
print(f"\n [[y for y in x] for x in m] → {ichma_ich}")
print(f" ⭐ ICHMA-ICH (nusxa)")
print(f"\n [[y*2 for y in x] for x in m] → {ikkilangan}")
print(f"\n ⚠️ Tartib — sikldagi kabi:")
print(f"""
[y for x in m for y in x]
↑ ↑ ↑
ifoda 1-for 2-for
Ekvivalenti:
for x in m: ← BIRINCHI
for y in x: ← IKKINCHI
natija.append(y)
""")
print(f" Bog'liq ichma-ich:")
print(f" [(i,j) for i in range(3) for j in range(i)]")
print(f" → {[(i, j) for i in range(3) for j in range(i)]}")
print(f"\n Uch daraja:")
uch = [x for a in [[[1, 2]], [[3], [4, 5]]] for b in a for x in b]
print(f" [[[1,2]], [[3],[4,5]]] → {uch}")
print(f"\n Har for dan keyin if:")
natija = [y for x in MATRITSA if len(x) > 2 for y in x if y % 2 == 0]
print(f" [y for x in m if len(x)>2 for y in x if y%2==0]")
print(f" → {natija}")
print(f" (uzunligi > 2 bo'lgan qatorlardan juft sonlar)")
print("\n=== 5. Matritsa amallari ===")
M = [[1, 2, 3], [4, 5, 6]]
print(f" M = {M}\n")
AMALLAR = [
("Transponirlash", [[M[i][j] for i in range(len(M))] for j in range(len(M[0]))]),
("zip bilan (⭐)", [list(q) for q in zip(*M)]),
("Har elementga *2", [[x * 2 for x in qator] for qator in M]),
("Qatorlar yig'indisi", [sum(qator) for qator in M]),
("Ustunlar yig'indisi", [sum(q) for q in zip(*M)]),
("Tekislash", [x for qator in M for x in qator]),
("Diagonal", [M[i][i] for i in range(min(len(M), len(M[0])))]),
]
for nom, natija in AMALLAR:
print(f" {nom:<24} {natija}")
print(f"\n Birlik matritsa:")
n = 4
birlik = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
for qator in birlik:
print(f" {qator}")
print(f"\n Ko'paytirish jadvali:")
jadval = [[i * j for j in range(1, 6)] for i in range(1, 6)]
print(f" " + "".join(f"{j:>5}" for j in range(1, 6)))
for i, qator in enumerate(jadval, 1):
print(f" {i:>2} " + "".join(f"{x:>5}" for x in qator))
print("\n=== 6. Bytecode ===")
print(" [x*2 for x in r]:")
dis.dis("[x*2 for x in r]")
print("\n Oddiy sikl:")
dis.dis("""
natija = []
for x in r:
natija.append(x*2)
""")
print("""
⭐ Generator: LIST_APPEND — maxsus bytecode
Sikl: LOAD_METHOD append + CALL_METHOD — har iteratsiyada
""")Natijaning muhim qismi:
=== 2. ⚠️ if filtri vs if/else ifodasi ===
SONLAR = [-3, -1, 0, 2, 4, 7]
[x for x in s if x > 0] → [2, 4, 7]
3 element (filtrlandi)
[x if x > 0 else 0 for x in s] → [0, 0, 0, 2, 4, 7]
6 element (hammasi)
=== 3. Bajarilish tartibi ===
Chaqiruvlar tartibi:
1. manba(0)
2. shart(0)
3. ifoda(0)
4. manba(1)
5. shart(1)
6. manba(2)
7. shart(2)
8. ifoda(2)
=== 4. Ichma-ich generatorlar ===
[y for x in m for y in x] → [1, 2, 3, 4, 5, 6, 7, 8, 9]
⭐ TEKIS
[[y for y in x] for x in m] → [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
⭐ ICHMA-ICH (nusxa)Nima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Qamrov va tuzoqlar
"""Generator qamrovi va kech bog'lanish."""
print("=== 1. O'zgaruvchi sizib chiqmaydi (Python 3) ===")
x = 10
natija = [x for x in range(3)]
print(f" x = 10")
print(f" [x for x in range(3)] → {natija}")
print(f" print(x) → {x} ✅ o'zgarmadi")
print("""
⚠️ Python 2 da x = 2 bo'lardi — generator o'zgaruvchisi sizardi.
Bu — Python 3 ning muhim tuzatishlaridan biri.
""")
print(" Ichkarida yashirin funksiya qamrovi bor:")
print("""
[x**2 for x in r] taxminan:
def _yashirin(it):
natija = []
for x in it:
natija.append(x**2)
return natija
_yashirin(iter(r))
""")
print("\n=== 2. Birinchi iterable tashqarida ===")
print(" Farqni ko'rsatish:\n")
try:
[x for x in aniqlanmagan_nom]
except NameError as e:
print(f" [x for x in aniqlanmagan] → NameError: {e}")
def sinov():
try:
return [aniqlanmagan_nom for x in range(3)]
except NameError as e:
return f"NameError: {e}"
print(f" [aniqlanmagan for x in r] → {sinov()}")
print("""
⭐ BIRINCHI `for` ning iterable'i tashqi qamrovda hisoblanadi,
qolgan hamma narsa — generator ichida.
""")
print("\n=== 3. ⚠️ Sinf tanasi ichida ===")
print(" ✅ Ishlaydigan:")
class A:
qiymatlar = [1, 2, 3]
ikkilangan = [x * 2 for x in qiymatlar] # birinchi for
print(f" class A:")
print(f" qiymatlar = [1, 2, 3]")
print(f" ikkilangan = [x*2 for x in qiymatlar]")
print(f" A.ikkilangan = {A.ikkilangan}")
print("\n ❌ Ishlamaydigan:")
try:
class B:
qiymatlar = [1, 2, 3]
juftliklar = [(x, y) for x in qiymatlar for y in qiymatlar]
except NameError as e:
print(f" class B:")
print(f" qiymatlar = [1, 2, 3]")
print(f" juftliklar = [(x,y) for x in qiymatlar for y in qiymatlar]")
print(f" → NameError: {e}")
print("""
Sabab:
• Birinchi `for` iterable'i — SINF qamrovida (ko'rinadi)
• Ikkinchi `for` — generator ichida (sinf qamrovi KO'RINMAYDI)
⭐ Sinf tanasi — oddiy qamrov emas: u funksiyalar ichidan
ko'rinmaydi. Generator esa yashirin funksiya.
""")
print(" ✅ Yechimlar:")
class C:
qiymatlar = [1, 2, 3]
@classmethod
def juftliklar(cls):
return [(x, y) for x in cls.qiymatlar for y in cls.qiymatlar]
print(f" 1. Metod ichida: C.juftliklar() = {C.juftliklar()[:3]}...")
QIYMATLAR = [1, 2, 3]
class D:
qiymatlar = QIYMATLAR
juftliklar = [(x, y) for x in QIYMATLAR for y in QIYMATLAR]
print(f" 2. Modul darajasida: D.juftliklar[:3] = {D.juftliklar[:3]}...")
print("\n=== 4. ⚠️ Kech bog'lanish (late binding) ===")
funksiyalar = [lambda: i for i in range(3)]
natijalar = [f() for f in funksiyalar]
print(f" funksiyalar = [lambda: i for i in range(3)]")
print(f" [f() for f in funksiyalar] → {natijalar} ⚠️ hammasi 2!")
print("""
Sabab: lambda `i` ni HISOBLAMAYDI, faqat unga havola saqlaydi.
Sikl tugaganda i == 2, va uchala lambda ham shuni ko'radi.
""")
print(" ✅ Yechimlar:\n")
f1 = [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)] → {[f() for f in f1]}")
from functools import partial
f2 = [partial(lambda x: x, i) for i in range(3)]
print(f"\n 2. functools.partial:")
print(f" [partial(lambda x: x, i) ...] → {[f() for f in f2]}")
def yaratuvchi(i):
return lambda: i
f3 = [yaratuvchi(i) for i in range(3)]
print(f"\n 3. Yaratuvchi funksiya:")
print(f" [yaratuvchi(i) for i in range(3)] → {[f() for f in f3]}")
print("""
⚠️ Bu — generator emas, LAMBDA muammosi.
Oddiy siklda ham xuddi shunday bo'ladi.
""")
f4 = []
for i in range(3):
f4.append(lambda: i)
print(f" Siklda ham: {[f() for f in f4]} ⚠️ bir xil")
print("\n=== 5. Iteratsiya paytida o'zgartirish ===")
r = [1, 2, 3, 4, 5]
print(f" r = {r}\n")
print(f" ✅ Generator yangi ro'yxat yaratadi:")
r2 = [x for x in r if x % 2 == 0]
print(f" r2 = [x for x in r if x%2==0] → r2={r2}, r={r}")
print(f"\n ✅ Joyida almashtirish:")
r3 = [1, 2, 3, 4, 5]
r3[:] = [x for x in r3 if x % 2 == 0]
print(f" r[:] = [x for x in r if ...] → {r3}")
print(f" ⭐ Havolalar saqlanadi (6.2-dars)")
print(f"\n ⚠️ Generator ichida asl ro'yxatni o'zgartirish:")
r4 = [1, 2, 3]
natija = [r4.append(x) or x for x in r4[:]] # nusxa bo'yicha
print(f" Nusxa bo'yicha iteratsiya → natija={natija}, r={r4}")
print("\n=== 6. Ichma-ich ro'yxat va nusxa ===")
ASL = [[1, 2], [3, 4]]
sayoz1 = [qator for qator in ASL]
sayoz2 = ASL.copy()
chuqur = [qator[:] for qator in ASL]
print(f" ASL = {ASL}\n")
print(f" {'Usul':<32} {'ASL[0] is nusxa[0]'}")
print(" " + "─" * 54)
print(f" {'[qator for qator in ASL]':<32} {ASL[0] is sayoz1[0]}")
print(f" {'ASL.copy()':<32} {ASL[0] is sayoz2[0]}")
print(f" {'[qator[:] for qator in ASL]':<32} {ASL[0] is chuqur[0]}")
sayoz1[0].append(99)
print(f"\n sayoz1[0].append(99) → ASL = {ASL} ⚠️")
ASL[0].remove(99)
chuqur[0].append(99)
print(f" chuqur[0].append(99) → ASL = {ASL} ✅")
print("""
⭐ [qator for qator in m] — SAYOZ (ichki ro'yxatlar umumiy)
[qator[:] for qator in m] — bir daraja chuqur
copy.deepcopy(m) — to'liq (18-dars)
""")Natijaning muhim qismi:
=== 3. ⚠️ Sinf tanasi ichida ===
✅ Ishlaydigan:
A.ikkilangan = [2, 4, 6]
❌ Ishlamaydigan:
→ NameError: name 'qiymatlar' is not defined
=== 4. ⚠️ Kech bog'lanish (late binding) ===
funksiyalar = [lambda: i for i in range(3)]
[f() for f in funksiyalar] → [2, 2, 2] ⚠️ hammasi 2!
✅ Yechimlar:
1. Sukut argument:
[lambda i=i: i for i in range(3)] → [0, 1, 2]
=== 6. Ichma-ich ro'yxat va nusxa ===
Usul ASL[0] is nusxa[0]
──────────────────────────────────────────────────────
[qator for qator in ASL] True
ASL.copy() True
[qator[:] for qator in ASL] FalseNima ko'rsatdi: 2.3-bo'lim.
Misol 3 — Tezlik va muqobillar
"""Generator vs sikl vs map vs numpy."""
import timeit
import sys
from itertools import chain, product, starmap
print("=== 1. Generator vs sikl ===")
SOZLASH = "r = list(range(1000))"
SINOVLAR = [
("[x*2 for x in r]", "[x*2 for x in r]"),
("sikl + append", "n=[]\nfor x in r: n.append(x*2)"),
("sikl + append (lokal)", "n=[]\nq=n.append\nfor x in r: q(x*2)"),
("list(map(...))", "list(map(lambda x: x*2, r))"),
("list(map(operator))", "from operator import mul\n"
"from functools import partial\n"
"list(map(partial(mul, 2), r))"),
]
natijalar = []
for nom, kod in SINOVLAR:
vaqt = timeit.timeit(kod, setup=SOZLASH, number=20_000)
natijalar.append((nom, vaqt))
eng_tez = min(v for _, v in natijalar)
print(f" 1000 element × 20 000 marta:\n")
print(f" {'Usul':<28} {'Vaqt':>9} {'Nisbat':>9}")
print(" " + "─" * 50)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
print(f" {nom:<28} {vaqt:>7.3f} s {vaqt / eng_tez:>8.2f}x")
print("""
⭐ Generator tezroq, chunki:
• LIST_APPEND — maxsus bytecode
• `.append` atributi har iteratsiyada qidirilmaydi
• Natija hajmi oldindan taxmin qilinadi
""")
print("\n=== 2. Funksiya chaqiruvi bilan ===")
def qimmat(x):
return sum(range(x % 50))
SOZLASH2 = """
r = list(range(500))
def qimmat(x): return sum(range(x % 50))
"""
SINOVLAR2 = [
("[qimmat(x) for x in r]", "[qimmat(x) for x in r]"),
("sikl + append", "n=[]\nfor x in r: n.append(qimmat(x))"),
("list(map(qimmat, r))", "list(map(qimmat, r))"),
]
natijalar = []
for nom, kod in SINOVLAR2:
vaqt = timeit.timeit(kod, setup=SOZLASH2, number=2_000)
natijalar.append((nom, vaqt))
eng_tez = min(v for _, v in natijalar)
print(f" Qimmat funksiya bilan:\n")
print(f" {'Usul':<28} {'Vaqt':>9} {'Nisbat':>9}")
print(" " + "─" * 50)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
print(f" {nom:<28} {vaqt:>7.3f} s {vaqt / eng_tez:>8.2f}x")
print("""
⭐ Funksiya qimmat bo'lsa, farq YO'QOLADI —
`append` narxi umumiy vaqtning kichik qismiga aylanadi.
""")
print("\n=== 3. map qachon yaxshiroq ===")
SOZLASH3 = "sozlar = ['salom', 'dunyo', 'python'] * 300"
SINOVLAR3 = [
("[s.upper() for s in sozlar]", "[s.upper() for s in sozlar]"),
("list(map(str.upper, sozlar))", "list(map(str.upper, sozlar))"),
("list(map(lambda s: s.upper(), ...))",
"list(map(lambda s: s.upper(), sozlar))"),
]
natijalar = []
for nom, kod in SINOVLAR3:
vaqt = timeit.timeit(kod, setup=SOZLASH3, number=20_000)
natijalar.append((nom, vaqt))
eng_tez = min(v for _, v in natijalar)
print(f" {'Usul':<40} {'Vaqt':>9} {'Nisbat':>9}")
print(" " + "─" * 62)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
print(f" {nom:<40} {vaqt:>7.3f} s {vaqt / eng_tez:>8.2f}x")
print("""
⭐ Qoida:
• Tayyor funksiya (str.upper, int, len) → map biroz tezroq
• lambda yozish kerak → generator
• O'qilish muhim → generator
""")
print("\n=== 4. itertools muqobillari ===")
M = [[1, 2], [3, 4], [5, 6]]
A, B = [1, 2, 3], ["a", "b"]
JUFTLIKLAR = [(1, 2), (3, 4)]
def qoshish(x, y):
return x + y
MUQOBILLAR = [
("Tekislash",
[y for x in M for y in x],
list(chain.from_iterable(M))),
("Dekart ko'paytmasi",
[(i, j) for i in A for j in B],
list(product(A, B))),
("Argumentlarni ochish",
[qoshish(*args) for args in JUFTLIKLAR],
list(starmap(qoshish, JUFTLIKLAR))),
]
print(f" {'Vazifa':<24} {'Generator':<26} {'itertools'}")
print(" " + "─" * 68)
for nom, gen, it in MUQOBILLAR:
belgi = "✅" if gen == it else "❌"
print(f" {nom:<24} {str(gen)[:24]:<26} {belgi} {str(it)[:20]}")
print(f"\n Tezlik (tekislash, 1000 qator):")
SOZLASH4 = "m = [[i, i+1] for i in range(1000)]"
for nom, kod in [("[y for x in m for y in x]", "[y for x in m for y in x]"),
("chain.from_iterable(m)",
"from itertools import chain\nlist(chain.from_iterable(m))")]:
vaqt = timeit.timeit(kod, setup=SOZLASH4, number=10_000)
print(f" {nom:<32} {vaqt:.3f} s")
print("\n=== 5. Xotira: ro'yxat vs generator ifodasi ===")
N = 1_000_000
royxat = [x ** 2 for x in range(N)]
gen = (x ** 2 for x in range(N))
print(f" {N:,} element:\n")
print(f" Ro'yxat generatori: {sys.getsizeof(royxat):>12,} bayt")
print(f" Generator ifodasi: {sys.getsizeof(gen):>12,} bayt")
print(f" Farq: {sys.getsizeof(royxat) / sys.getsizeof(gen):>12,.0f}x")
print(f"\n Natija bir xil:")
print(f" sum([x**2 for x in range(1000)]) = {sum([x ** 2 for x in range(1000)]):,}")
print(f" sum(x**2 for x in range(1000)) = {sum(x ** 2 for x in range(1000)):,}")
print(f"\n Tezlik:")
for nom, kod in [("sum([...])", "sum([x**2 for x in range(10000)])"),
("sum(...)", "sum(x**2 for x in range(10000))")]:
vaqt = timeit.timeit(kod, number=2_000)
print(f" {nom:<16} {vaqt:.3f} s")
print("""
⚠️ Generator ifodasi biroz SEKINROQ (har element uchun
yield mexanizmi), lekin xotira 40 000x kam.
⭐ Katta ma'lumot → generator ifodasi (17-dars)
Kichik ma'lumot + qayta ishlatish → ro'yxat
""")
del royxat
print("\n=== 6. numpy bilan ===")
try:
import numpy as np
N = 1_000_000
r = list(range(N))
a = np.arange(N)
import time
boshlandi = time.perf_counter()
n1 = [x ** 2 for x in r]
vaqt_gen = time.perf_counter() - boshlandi
boshlandi = time.perf_counter()
n2 = a ** 2
vaqt_np = time.perf_counter() - boshlandi
print(f" {N:,} element kvadrati:\n")
print(f" [x**2 for x in r]: {vaqt_gen * 1000:>8.1f} ms")
print(f" numpy a**2: {vaqt_np * 1000:>8.1f} ms")
print(f" Farq: {vaqt_gen / vaqt_np:>8.0f}x")
print(f"\n Xotira:")
print(f" list: {sys.getsizeof(n1):>12,} bayt (+ obyektlar)")
print(f" numpy: {n2.nbytes:>12,} bayt")
del n1, n2
print("""
⭐ Bir turdagi sonli massivlar uchun numpy —
vektorlashtirilgan amallar C darajasida bajariladi.
24-qismda batafsil.
""")
except ImportError:
print(" (numpy o'rnatilmagan — o'tkazib yuborildi)")Natijaning muhim qismi:
=== 1. Generator vs sikl ===
1000 element × 20 000 marta:
Usul Vaqt Nisbat
──────────────────────────────────────────────────
[x*2 for x in r] 0.842 s 1.00x
sikl + append (lokal) 1.124 s 1.33x
sikl + append 1.512 s 1.80x
list(map(...)) 1.284 s 1.52x
=== 2. Funksiya chaqiruvi bilan ===
Qimmat funksiya bilan:
Usul Vaqt Nisbat
──────────────────────────────────────────────────
list(map(qimmat, r)) 1.812 s 1.00x
[qimmat(x) for x in r] 1.884 s 1.04x
sikl + append 1.941 s 1.07x
=== 5. Xotira: ro'yxat vs generator ifodasi ===
1,000,000 element:
Ro'yxat generatori: 8,448,728 bayt
Generator ifodasi: 208 bayt
Farq: 40,619xNima ko'rsatdi: 2.4, 2.6-bo'limlar.
Misol 4 — Amaliy: ma'lumot qayta ishlash
"""Generatorlar bilan real vazifalar va o'qilish chegarasi."""
import re
from collections import Counter
print("=== 1. Matn qayta ishlash ===")
MATN = """
Python — kuchli va oddiy dasturlash tili. Python o'rganish oson,
lekin uning imkoniyatlari juda keng! Dasturlash tili sifatida
Python veb, ma'lumot tahlili va sun'iy intellektda ishlatiladi?
"""
TOXTASH = {"va", "u", "bu", "uchun", "bilan", "lekin", "ham", "sifatida"}
qatorlar = [q.strip() for q in MATN.strip().splitlines()]
sozlar = [s.lower().strip(".,!?—") for q in qatorlar for s in q.split()]
mazmunli = [s for s in sozlar if s and s not in TOXTASH]
uzunlar = [s for s in mazmunli if len(s) > 6]
print(f" Qatorlar: {len(qatorlar)}")
print(f" Jami so'zlar: {len(sozlar)}")
print(f" Mazmunli: {len(mazmunli)}")
print(f" Uzun (>6): {len(uzunlar)}\n")
print(f" Uzun so'zlar: {uzunlar}")
hisob = Counter(mazmunli)
print(f"\n Eng ko'p uchraganlar:")
for soz, n in hisob.most_common(5):
print(f" {soz:<16} {'█' * n} {n}")
print(f"\n Uzunlik bo'yicha guruhlash:")
uzunliklar = sorted({len(s) for s in mazmunli})
for n in uzunliklar[-4:]:
guruh = sorted({s for s in mazmunli if len(s) == n})
print(f" {n:>2} harf: {', '.join(guruh)}")
print("\n\n=== 2. Ma'lumot filtrlash va o'zgartirish ===")
XODIMLAR = [
{"ism": "Aziz", "yosh": 30, "bolim": "IT", "maosh": 7_000_000, "faol": True},
{"ism": "Bobur", "yosh": 25, "bolim": "HR", "maosh": 5_000_000, "faol": True},
{"ism": "Aziza", "yosh": 35, "bolim": "IT", "maosh": 8_500_000, "faol": False},
{"ism": "Dilnoza", "yosh": 28, "bolim": "Moliya", "maosh": 6_000_000, "faol": True},
{"ism": "Eldor", "yosh": 42, "bolim": "IT", "maosh": 9_000_000, "faol": True},
]
SOROVLAR = [
("Barcha ismlar",
[x["ism"] for x in XODIMLAR]),
("Faol xodimlar",
[x["ism"] for x in XODIMLAR if x["faol"]]),
("IT bo'limi",
[x["ism"] for x in XODIMLAR if x["bolim"] == "IT"]),
("Maoshi 6M dan yuqori",
[x["ism"] for x in XODIMLAR if x["maosh"] > 6_000_000]),
("Faol IT xodimlari",
[x["ism"] for x in XODIMLAR if x["faol"] and x["bolim"] == "IT"]),
("Ism + maosh",
[(x["ism"], x["maosh"]) for x in XODIMLAR if x["faol"]]),
("15% oshirilgan maosh",
[{**x, "maosh": round(x["maosh"] * 1.15)} for x in XODIMLAR if x["bolim"] == "IT"]),
]
for nom, natija in SOROVLAR[:6]:
print(f" {nom:<26} {natija}")
print(f"\n 15% oshirilgan (IT):")
for x in SOROVLAR[6][1]:
print(f" {x['ism']:<10} {x['maosh']:>10,}")
print(f"\n Statistika:")
maoshlar = [x["maosh"] for x in XODIMLAR if x["faol"]]
print(f" Faol xodimlar: {len(maoshlar)}")
print(f" O'rtacha maosh: {sum(maoshlar) // len(maoshlar):,}")
print(f" Eng katta: {max(maoshlar):,}")
bolimlar = {x["bolim"] for x in XODIMLAR}
print(f"\n Bo'lim bo'yicha:")
for b in sorted(bolimlar):
guruh = [x for x in XODIMLAR if x["bolim"] == b]
jami = sum(x["maosh"] for x in guruh)
print(f" {b:<10} {len(guruh)} xodim, jami {jami:>12,}")
print("\n\n=== 3. ⚠️ O'qilish chegarasi ===")
print(" ❌ Juda murakkab (3 for + 2 if):\n")
print(""" natija = [transform(x, y, z)
for x in manba if shart1(x)
for y in x.bolalar if shart2(x, y)
for z in y.bolalar if shart3(z)]
""")
print(" ✅ Oddiy sikl — o'qish oson, tuzatish oson:\n")
print(""" natija = []
for x in manba:
if not shart1(x):
continue
for y in x.bolalar:
if not shart2(x, y):
continue
for z in y.bolalar:
if shart3(z):
natija.append(transform(x, y, z))
""")
print(" ✅ Yoki funksiyalarga ajrating:\n")
print(""" def mos_bolalar(x):
return [y for y in x.bolalar if shart2(x, y)]
natija = [transform(x, y, z)
for x in manba if shart1(x)
for y in mos_bolalar(x)
for z in y.bolalar if shart3(z)]
""")
print(""" ⭐ Amaliy qoida:
• 1 ta for + 1 ta if → generator ✅
• 2 ta for yoki 2 ta if → generator, agar qisqa bo'lsa
• 3 va undan ko'p → sikl yoki funksiya ajrating
• Bir qatorga sig'masa → qayta o'ylang
""")
print("\n=== 4. ❌ Yon ta'sir uchun ishlatmang ===")
print(" ❌ Noto'g'ri:")
print(""" [print(x) for x in r] # keraksiz ro'yxat
[d.update({x: 1}) for x in r] # None lar ro'yxati
[f.write(q) for q in qatorlar] # yozuv soni ro'yxati
""")
r = [1, 2, 3]
natija = [print(f" {x}", end="") for x in r]
print(f"\n Yaratilgan ro'yxat: {natija} ⚠️ keraksiz")
print("\n ✅ To'g'ri:")
print(""" for x in r: print(x)
for x in r: d[x] = 1
f.writelines(qatorlar)
""")
print("""
⭐ Generator — QIYMAT yaratish uchun.
Yon ta'sir uchun — sikl.
""")
print("\n=== 5. Amaliy: log tahlili ===")
LOGLAR = [
'192.168.1.1 - [08/Sep/2026:10:00:01] "GET / HTTP/1.1" 200 1234',
'192.168.1.2 - [08/Sep/2026:10:00:05] "POST /api HTTP/1.1" 201 567',
'notogri qator',
'192.168.1.1 - [08/Sep/2026:10:00:12] "GET /admin HTTP/1.1" 403 89',
'192.168.1.3 - [08/Sep/2026:10:00:15] "GET /api HTTP/1.1" 500 234',
'192.168.1.1 - [08/Sep/2026:10:00:20] "GET /static/a.js HTTP/1.1" 304 0',
]
NAQSH = re.compile(
r'(?P<ip>[\d.]+) - \[(?P<vaqt>[^\]]+)\] '
r'"(?P<usul>\w+) (?P<yol>\S+) [^"]*" (?P<kod>\d+) (?P<hajm>\d+)'
)
# Bir bosqichda: parse + filtrlash
moslar = [m.groupdict() for q in LOGLAR if (m := NAQSH.match(q))]
print(f" {len(LOGLAR)} qator → {len(moslar)} to'g'ri\n")
print(f" ⭐ Walrus operatori (:=) bilan bir bosqichda:")
print(f" [m.groupdict() for q in LOGLAR if (m := NAQSH.match(q))]")
print(f" ← parse bir marta bajariladi\n")
print(f" ❌ Walrus siz — ikki marta parse:")
print(f" [NAQSH.match(q).groupdict() for q in LOGLAR if NAQSH.match(q)]\n")
xatolar = [m for m in moslar if int(m["kod"]) >= 400]
noyob_ip = sorted({m["ip"] for m in moslar})
yollar = Counter(m["yol"] for m in moslar)
trafik = sum(int(m["hajm"]) for m in moslar)
print(f" Statistika:")
print(f" To'g'ri qatorlar: {len(moslar)}")
print(f" Xatolar (4xx/5xx): {len(xatolar)}")
print(f" Noyob IP: {len(noyob_ip)} {noyob_ip}")
print(f" Jami trafik: {trafik:,} bayt")
print(f"\n Xato so'rovlar:")
for m in xatolar:
print(f" {m['kod']} {m['usul']:<5} {m['yol']:<16} {m['ip']}")
print(f"\n Eng ko'p so'ralgan yo'llar:")
for yol, n in yollar.most_common(3):
print(f" {yol:<18} {'█' * n} {n}")
print(f"\n IP bo'yicha:")
for ip in noyob_ip:
ip_soraovlar = [m for m in moslar if m["ip"] == ip]
ip_yollar = sorted({m["yol"] for m in ip_soraovlar})
print(f" {ip:<16} {len(ip_soraovlar)} so'rov: {', '.join(ip_yollar)}")
print("\n\n=== 6. To'rt generator turi ===")
MALUMOT = ["olma", "anor", "olma", "behi", "anor", "olma"]
print(f" Ma'lumot: {MALUMOT}\n")
TURLARI = [
("[x.upper() for x in m]", [x.upper() for x in MALUMOT]),
("{x.upper() for x in m}", {x.upper() for x in MALUMOT}),
("{x: len(x) for x in m}", {x: len(x) for x in MALUMOT}),
("(x.upper() for x in m)", (x.upper() for x in MALUMOT)),
("tuple(x for x in m)", tuple(x for x in MALUMOT)),
]
for kod, natija in TURLARI:
tur = type(natija).__name__
korinish = str(natija) if tur != "generator" else "<generator obyekti>"
print(f" {kod:<28} {tur:<10} {korinish[:36]}")
print("""
⚠️ (x for x in m) — GENERATOR, tuple emas!
tuple(x for x in m) — tuple
16-dars: set va dict generatorlari
17-dars: generator ifodalari
""")Natijaning muhim qismi:
=== 2. Ma'lumot filtrlash va o'zgartirish ===
Barcha ismlar ['Aziz', 'Bobur', 'Aziza', 'Dilnoza', 'Eldor']
Faol xodimlar ['Aziz', 'Bobur', 'Dilnoza', 'Eldor']
IT bo'limi ['Aziz', 'Aziza', 'Eldor']
Faol IT xodimlari ['Aziz', 'Eldor']
=== 5. Amaliy: log tahlili ===
6 qator → 5 to'g'ri
Statistika:
To'g'ri qatorlar: 5
Xatolar (4xx/5xx): 2
Noyob IP: 3 ['192.168.1.1', '192.168.1.2', '192.168.1.3']
Jami trafik: 2,124 bayt
=== 6. To'rt generator turi ===
[x.upper() for x in m] list ['OLMA', 'ANOR', 'OLMA', 'BEHI', ...
{x.upper() for x in m} set {'BEHI', 'OLMA', 'ANOR'}
{x: len(x) for x in m} dict {'olma': 4, 'anor': 4, 'behi': 4}
(x.upper() for x in m) generator <generator obyekti>Nima ko'rsatdi: 2.1, 2.5, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"[x for x in s if x > 0 else 0] ishlaydi" |
SyntaxError. if/else oldinda |
"Ichma-ich for lar o'ngdan chapga" |
Chapdan o'ngga, sikldagi kabi |
| "Generator o'zgaruvchisi tashqariga sizadi" | Python 3 da yo'q |
| "Generator har doim tezroq" | Funksiya chaqiruvi bo'lsa farq yo'q |
"map har doim tezroq" |
Faqat tayyor funksiya bilan |
"(x for x in r) — tuple generatori" |
Generator ifodasi |
| "Yon ta'sir uchun ham ishlatsa bo'ladi" | Ishlaydi, lekin noto'g'ri uslub |
"Sinf tanasida ikki for ishlaydi" |
NameError |
"[qator for qator in m] — chuqur nusxa" |
Sayoz — ichki ro'yxatlar umumiy |
6. Keng tarqalgan xatolar va yechimlari
1. if/else joyi
[x for x in s if x > 0 else 0] # ❌ SyntaxError
[x if x > 0 else 0 for x in s] # ✅2. Ichma-ich tartib
[y for y in x for x in m] # ❌ NameError (x hali yo'q)
[y for x in m for y in x] # ✅3. Yon ta'sir
[print(x) for x in r] # ❌ keraksiz ro'yxat
for x in r: print(x) # ✅4. Katta ma'lumot
sum([x**2 for x in range(10**7)]) # ⚠️ ~400 MB
sum(x**2 for x in range(10**7)) # ✅ ~200 bayt5. Kech bog'lanish
[lambda: i for i in range(3)] # ⚠️ hammasi 2
[lambda i=i: i for i in range(3)] # ✅6. Ikki marta hisoblash
[f(x) for x in r if f(x) > 0] # ⚠️ f ikki marta
[y for x in r if (y := f(x)) > 0] # ✅ walrus (3.8+)7. Sayoz nusxa
nusxa = [qator for qator in m] # ⚠️ ichki ro'yxatlar umumiy
nusxa = [qator[:] for qator in m] # ✅ bir daraja
nusxa = copy.deepcopy(m) # ✅ to'liq8. Juda murakkab
[f(x,y,z) for x in a if p(x) for y in x if q(y) for z in y] # ❌
# → oddiy sikl yoki funksiyalarga ajrating7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 6.16-dars:
setvadictgeneratorlari - 6.17-dars: generator ifodalari — xotira tejash
- 5.6, 5.7-darslar (o'tilgan):
for,range, iteratsiya - 7-qism:
lambda,map,filter,functools - 10, 15-qismlar: funksional dasturlash,
itertools - 6.14-dars (o'tilgan): ichma-ich tuzilmalar bilan
- 24-qism:
numpy— vektorlashtirilgan amallar
8. Eng yaxshi amaliyotlar
Bir
for+ birif— ideal. Ikkitadan ko'p bo'lsa sikl haqida o'ylang.if/else— ifoda,if— filtr. Joylarini chalkashtirmang.Yon ta'sir uchun sikl. Generator qiymat yaratadi.
Katta ma'lumot uchun generator ifodasi.
sum(x for ...),[]siz.Ichma-ich
for— sikldagi tartibda. Chapdan o'ngga.Tayyor funksiya bilan
mapni ko'rib chiqing.lambdakerak bo'lsa — generator.Walrus bilan takroriy hisoblashdan qoching.
if (y := f(x)).O'qib bo'lmasa — qayta yozing. Qisqalik o'qilishdan muhim emas.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
1. print([x*2 for x in range(4)])
2. print([x for x in range(6) if x % 2])
3. print([x if x % 2 else 0 for x in range(6)])
4. print([y for x in [[1,2],[3]] for y in x])
5. print([[y for y in x] for x in [[1,2],[3]]])
6. print([(i,j) for i in range(3) for j in range(i)])
7. x = 5; [x for x in range(3)]; print(x)
8. print([f() for f in [lambda: i for i in range(3)]])
9. print([f() for f in [lambda i=i: i for i in range(3)]])
10. print(type((x for x in range(3))))
11. print([len(s) for s in "ab cd".split()])
12. print(len([print(x) for x in range(2)]))Javoblar
[0, 2, 4, 6][1, 3, 5]— filtr[0, 1, 0, 3, 0, 5]— ifoda[1, 2, 3]— tekis[[1, 2], [3]]— ichma-ich[(1, 0), (2, 0), (2, 1)]5— sizmaydi[2, 2, 2]— kech bog'lanish[0, 1, 2]— sukut argument<class 'generator'>— tuple emas![2, 2]0va1chiqadi, keyin2—Nonelar ro'yxati uzunligi
Vazifa 2: Xatolarni tuzating
1. [x for x in s if x > 0 else 0]
2. [y for y in x for x in m]
3. [print(x) for x in r]
4. jami = sum([x**2 for x in range(10**7)])
5. [f(x) for x in r if f(x) > 0]
6. nusxa = [q for q in matritsa] # mustaqil bo'lishi kerak
7. fs = [lambda: i for i in range(3)]
8. class A:
q = [1,2]
j = [(x,y) for x in q for y in q]Javoblar
1. [x if x > 0 else 0 for x in s]
2. [y for x in m for y in x]
3. for x in r: print(x)
4. jami = sum(x**2 for x in range(10**7))
5. [y for x in r if (y := f(x)) > 0]
6. nusxa = [q[:] for q in matritsa]
7. fs = [lambda i=i: i for i in range(3)]
8. Q = [1,2] # modul darajasida
class A:
q = Q
j = [(x,y) for x in Q for y in Q]Vazifa 3: Generatorga aylantiring
Har bir siklni generatorga aylantiring (yoki "sikl yaxshiroq" deb izohlang):
1. n=[]
for x in r: n.append(x*2)
2. n=[]
for x in r:
if x > 0: n.append(x)
3. n=[]
for q in matritsa:
for x in q: n.append(x)
4. n=[]
for x in r:
if x > 0: n.append(x)
else: n.append(0)
5. jami = 0
for x in r: jami += x
6. for x in r: print(x)
7. n = {}
for x in r: n[x] = len(x)
8. n=[]
for x in a:
for y in b:
if p(x,y): n.append(f(x,y))Vazifa 4: Matritsa kutubxonasi
Generatorlar bilan yozing:
transponir(m)— transponirlashkopaytir(a, b)— matritsalar ko'paytmasibirlik(n)— birlik matritsaqoshish(a, b)— element bo'yichaminor(m, i, j)— i-qator, j-ustunsizaylantir(m)— 90° burish- Har biri uchun sikl versiyasi bilan tezlikni solishtiring
Vazifa 5: Ma'lumot quvuri
CSV kabi ma'lumot bilan:
- Parse (walrus bilan bir bosqichda)
- Filtrlash (bir necha shart)
- Turlarni aylantirish
- Guruhlash va agregatsiya
- Saralash va cheklash
- Har qadamni generator bilan, keyin sikl bilan yozing
- O'qilish va tezlikni solishtiring
Vazifa 6: O'qilish tahlilchisi
Dastur yozing:
- Kod faylidan generatorlarni topsin (
astmoduli bilan) - Har biri uchun murakkablikni baholasin (
forvaifsoni) - Uzunligini o'lchasin
- Chegaradan oshganlarni belgilasin
- Sikl versiyasini taklif qilsin
Vazifa 7: O'ylash
Nega Python [x for x in r] ni oddiy sikldan tezroq qildi, lekin (x for x in r) (generator ifodasi) sekinroq?
Javob
Ular turli narsalarni optimallashtiradi.
Ro'yxat generatori — bajarilish tezligi:
CPython [x for x in r] uchun maxsus bytecode beradi:
LIST_APPEND nBu — bitta instruksiya. Oddiy sikl esa:
LOAD_NAME natija
LOAD_METHOD append ← lug'atdan qidirish
LOAD_FAST x
CALL_METHOD 1 ← funksiya chaqiruvi
POP_TOP ← None ni tashlashBeshta instruksiya, ikkitasi qimmat (atribut qidiruvi va metod chaqiruvi).
Qo'shimcha: generator ro'yxat hajmini oldindan taxmin qiladi (kirish __len__ bo'lsa) — kamroq qayta ajratish.
Natija: ~1.8x tezroq.
Generator ifodasi — xotira, tezlik emas:
(x for x in r) generator obyekti yaratadi. Har next() chaqiruvida:
- Generator freym'i tiklanadi (holat: qayerda to'xtagan edi)
- Bir qadam bajariladi
yieldda to'xtaydi, freym saqlanadi- Qiymat qaytariladi
Bu — freym almashish (frame switching). U arzon emas: ~50-100 ns har element uchun.
Ro'yxat generatorida esa hamma narsa bir freymda bajariladi.
Natija:
sum([x for x in range(10**6)]) # ~45 ms
sum(x for x in range(10**6)) # ~65 ms ← ~45% sekinroqLekin xotira:
sys.getsizeof([x for x in range(10**6)]) # 8,448,728 bayt
sys.getsizeof(x for x in range(10**6)) # 208 bayt40 000x kam.
Savdo:
| Ro'yxat generatori | Generator ifodasi | |
|---|---|---|
| Tezlik | Tezroq | ~40% sekinroq |
| Xotira | O(n) | O(1) |
| Qayta o'tish | Bir marta | |
Indeks/len |
||
| Dangasa | Kerak bo'lganda |
Qachon qaysi biri:
# Kichik ma'lumot, qayta ishlatiladi → ro'yxat
kalitlar = [k for k in d if shart(k)]
for k in kalitlar: ...
for k in kalitlar: ... # ikkinchi marta
# Katta ma'lumot, bir marta → generator
jami = sum(x**2 for x in katta_fayl_qatorlari())
# Erta to'xtash → generator ⭐
birinchi = next(x for x in katta if shart(x))
any(shart(x) for x in katta) # birinchi True da to'xtaydiOxirgi holat ayniqsa muhim:
any([qimmat(x) for x in katta]) # ⚠️ HAMMASI hisoblanadi
any(qimmat(x) for x in katta) # ✅ birinchi True da to'xtaydiBu yerda generator tezroq ham bo'lishi mumkin — chunki u kamroq ish bajaradi.
Xulosa: "tezroq" savolining javobi kontekstga bog'liq. Ro'yxat generatori bir xil ishni tezroq bajaradi. Generator ifodasi kamroq ish bajarishga imkon beradi (dangasa hisoblash) va xotira tejaydi.
Amaliy qoida: natija to'liq kerak bo'lsa — ro'yxat, oqim sifatida ishlatilsa — generator.
Nimani mustahkamlaydi: 2.4, 2.5, 2.7-bo'limlar.
Xulosa
Bu darsda ro'yxat generatorlarini o'rgandik.
Eng muhim uch fikr:
iffiltri vaif/elseifodasi — turli joylarda.[x for x in s if x > 0]elementlarni tushiradi,[x if x > 0 else 0 for x in s]hammasini saqlaydi. Ikkinchisifordan oldin yoziladi.Ichma-ich
forlar sikldagi tartibda.[y for x in m for y in x]— avvalx, keyiny. Bu — eng ko'p chalkashtiradigan joy. Ikkita[]esa ichma-ich ro'yxat quradi.Generator — o'qilish uchun, tezlik uchun emas. U ~1.8x tezroq, lekin bu ikkinchi darajali. Ikkitadan ko'p
for/ifbo'lsa yoki yon ta'sir kerak bo'lsa — oddiy sikl yozing.
Keyingi darsda set va dict generatorlarini ko'ramiz: bir xil sintaksis, lekin noyoblik va kalit-qiymat semantikasi bilan.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!