IlmHamroh
Python kursi/Boshqaruv oqimi6/12-dars31 daqiqa
Mundarija (23)

5.6-dars: for sikli

5-QISM — BOSHQARUV OQIMI · 6-dars


1. Kirish va motivatsiya

for — Pythonda eng ko'p ishlatiladigan sikl. Va u boshqa tillardagi for dan jiddiy farq qiladi.

C, Java, JavaScript'da for — hisoblagichli sikl:

c
for (int i = 0; i < 10; i++) {
    printf("%d\n", i);
}

Pythonda esa for — to'plam bo'ylab yurish:

python
for element in toplam:
    print(element)

Bu farq — tasodifiy emas. Pythonning for i iteratsiya protokoli ga asoslangan va shuning uchun u:

python
for x in [1, 2, 3]:         # ro'yxat
for x in (1, 2, 3):         # juftlik
for x in "abc":             # satr
for x in {1, 2, 3}:         # to'plam
for k in {"a": 1}:          # lug'at
for x in range(10):         # diapazon
for qator in fayl:          # fayl
for x in generator():       # generator
for x in mening_sinfim:     # o'z sinfingiz

— hammasi bilan ishlaydi.

Bu darsda:

  • Iteratsiya protokoli — __iter__ va __next__
  • for ichkarida qanday ishlaydi
  • Iteratsiya paytida to'plamni o'zgartirish — klassik tuzoq
  • for/else
  • Ochish (unpacking) siklda
  • while dan qachon afzal

2. Nazariya — chuqur tushuntirish

2.1. Asosiy sintaksis

python
for <o'zgaruvchi> in <iteratsiya_qilinadigan>:
    <blok>
python
mevalar = ["olma", "anor", "uzum"]

for meva in mevalar:
    print(meva)
text
olma
anor
uzum

Sikl o'zgaruvchisi sikldan keyin ham mavjud:

python
for i in range(3):
    pass

print(i)                    # 2 — oxirgi qiymat

Bo'sh to'plamda o'zgaruvchi yaratilmaydi:

python
for i in []:
    pass

# print(i)                  # ❌ NameError

Bu — nozik xato manbai:

python
oxirgi = None
for oxirgi in royxat:
    ...
# oxirgi — endi kafolatlangan

Sikl o'zgaruvchisini o'zgartirish ta'sir qilmaydi:

python
for i in range(3):
    i = 100                 # keyingi iteratsiyada qayta yoziladi
    print(i, end=" ")
print()                     # 100 100 100

Chunki har iteratsiyada i ga yangi qiymat o'zlashtiriladi.

2.2. Iteratsiya protokoli

for ichkarida quyidagicha ishlaydi:

python
# Bu:
for x in toplam:
    ishla(x)

# Aslida bunga teng:
iterator = iter(toplam)         # 1. iterator olish
while True:
    try:
        x = next(iterator)      # 2. keyingi elementni olish
    except StopIteration:       # 3. tugadi
        break
    ishla(x)

Ikki funksiya:

python
royxat = [1, 2, 3]
it = iter(royxat)

print(type(it))             # <class 'list_iterator'>
print(next(it))             # 1
print(next(it))             # 2
print(next(it))             # 3
# print(next(it))           # ❌ StopIteration

Sukut qiymat bilan:

python
it = iter([1, 2])
print(next(it, "tugadi"))   # 1
print(next(it, "tugadi"))   # 2
print(next(it, "tugadi"))   # 'tugadi' — xato yo'q

Iteratsiya qilinadigan (iterable) va iterator — farq:

Iterable Iterator
Metod __iter__ __iter__ va __next__
Misol list, str, dict iter(royxat), generator
Qayta ishlatish Ha Yo'q — bir marta
python
royxat = [1, 2, 3]

# Iterable — bir necha marta
for x in royxat: pass
for x in royxat: pass       # ✅ ishlaydi

# Iterator — bir marta
it = iter(royxat)
for x in it: pass
for x in it: pass           # ❌ hech narsa — tugagan

Bu — generatorlar bilan ishlaganda muhim tuzoq (10-qism):

python
gen = (x * 2 for x in range(3))

print(list(gen))            # [0, 2, 4]
print(list(gen))            # [] — ikkinchi marta bo'sh!

O'z sinfingizni iteratsiya qilinadigan qilish (10-qism):

python
class Hisoblagich:
    def __init__(self, oxiri):
        self.oxiri = oxiri

    def __iter__(self):
        self.joriy = 0
        return self

    def __next__(self):
        if self.joriy >= self.oxiri:
            raise StopIteration
        self.joriy += 1
        return self.joriy


for x in Hisoblagich(3):
    print(x, end=" ")       # 1 2 3

Soddaroq — generator bilan:

python
class Hisoblagich:
    def __init__(self, oxiri):
        self.oxiri = oxiri

    def __iter__(self):
        for i in range(1, self.oxiri + 1):
            yield i

2.3. Nima bo'ylab yurish mumkin

Ketma-ketliklar:

python
for x in [1, 2, 3]: ...             # ro'yxat
for x in (1, 2, 3): ...             # juftlik
for c in "salom": ...               # satr — belgilar
for b in b"abc": ...                # baytlar — SONLAR
for x in range(5): ...              # diapazon

To'plamlar:

python
for x in {1, 2, 3}: ...             # to'plam — TARTIB YO'Q
for x in frozenset([1, 2]): ...

Lug'atlar:

python
lugat = {"a": 1, "b": 2}

for k in lugat: ...                 # KALITLAR
for k in lugat.keys(): ...          # kalitlar (aniq)
for v in lugat.values(): ...        # qiymatlar
for k, v in lugat.items(): ...      # juftliklar ⭐

for k in lugat — kalitlar, qiymatlar emas. Bu — keng tarqalgan chalkashlik.

Fayllar:

python
with open("fayl.txt", encoding="utf-8") as f:
    for qator in f:                 # qatorlar (\n bilan)
        print(qator.rstrip())

Bu — samarali: butun fayl xotiraga yuklanmaydi (16-qism).

Generatorlar:

python
for x in (i * 2 for i in range(3)): ...
for x in map(str, [1, 2, 3]): ...
for x in filter(None, [0, 1, 2]): ...
for x in zip([1, 2], "ab"): ...
for x in enumerate("abc"): ...

itertools (15-qism):

python
from itertools import count, cycle, chain, product

for x in chain([1, 2], "ab"): ...   # 1, 2, 'a', 'b'
for x in product([1, 2], "ab"): ... # (1,'a'), (1,'b'), (2,'a'), (2,'b')

2.4. Ochish (unpacking) siklda

Bu — Pythonning eng qulay imkoniyatlaridan biri:

python
juftliklar = [(1, "a"), (2, "b"), (3, "c")]

# ❌ Indeks bilan
for juftlik in juftliklar:
    print(juftlik[0], juftlik[1])

# ✅ Ochish bilan
for son, harf in juftliklar:
    print(son, harf)

Lug'at bilan:

python
for kalit, qiymat in lugat.items():
    print(f"{kalit}: {qiymat}")

enumerate bilan (8-dars):

python
for indeks, element in enumerate(royxat):
    print(f"{indeks}: {element}")

zip bilan (9-dars):

python
for ism, yosh in zip(ismlar, yoshlar):
    print(f"{ism}: {yosh}")

Ichma-ich ochish:

python
malumot = [("Ali", (25, "Toshkent")), ("Vali", (30, "Samarqand"))]

for ism, (yosh, shahar) in malumot:
    print(f"{ism}, {yosh}, {shahar}")

Yulduzcha bilan:

python
qatorlar = [
    ["Ali", 85, 90, 78],
    ["Vali", 92, 88, 95],
]

for ism, *ballar in qatorlar:
    print(f"{ism}: {ballar}, o'rtacha {sum(ballar) / len(ballar):.1f}")

_ — kerak emas qiymat (3.2-dars):

python
for _, qiymat in juftliklar:        # kalit kerak emas
    print(qiymat)

for _ in range(3):                  # sanoq kerak emas
    print("Salom")

Ochish uzunligi mos kelishi kerak:

python
for a, b in [(1, 2), (3, 4, 5)]:    # ❌ ValueError
    ...

2.5. Iteratsiya paytida to'plamni o'zgartirish

Bu — eng klassik tuzoq.

python
royxat = [1, 2, 3, 4, 5]

for x in royxat:
    if x % 2 == 0:
        royxat.remove(x)

print(royxat)               # [1, 3, 5] ← to'g'ri ko'rinadi, lekin...

Sinab ko'ring boshqa ma'lumot bilan:

python
royxat = [1, 2, 2, 3, 4, 4, 5]

for x in royxat:
    if x % 2 == 0:
        royxat.remove(x)

print(royxat)               # [1, 2, 3, 4, 5] ← BA'ZI juftlar qoldi!

Nima bo'lyapti?

text
Indeks:  0  1  2  3  4  5  6
Qiymat: [1, 2, 2, 3, 4, 4, 5]

i=0: x=1, o'chirilmadi
i=1: x=2, o'chirildi → [1, 2, 3, 4, 4, 5]
i=2: x=3 (ikkinchi 2 O'TKAZIB YUBORILDI — indeks siljidi)
i=3: x=4, o'chirildi → [1, 2, 3, 4, 5]
i=4: x=5

Element o'chirilganda indekslar siljiydi, iterator esa buni bilmaydi.

To'g'ri usullar:

python
# 1. Yangi ro'yxat yaratish (eng idiomatik)
royxat = [x for x in royxat if x % 2 != 0]

# 2. Nusxa bo'ylab yurish
for x in royxat[:]:         # ← nusxa
    if x % 2 == 0:
        royxat.remove(x)

# 3. Teskari yo'nalishda
for i in range(len(royxat) - 1, -1, -1):
    if royxat[i] % 2 == 0:
        del royxat[i]

# 4. filter
royxat = list(filter(lambda x: x % 2 != 0, royxat))

# 5. Joyida almashtirish (havolani saqlab)
royxat[:] = [x for x in royxat if x % 2 != 0]

5-usul muhim — agar ro'yxatga boshqa havolalar bo'lsa (3.1-dars):

python
a = [1, 2, 3, 4]
b = a

a = [x for x in a if x % 2]         # ❌ b o'zgarmadi
print(b)                            # [1, 2, 3, 4]

a = [1, 2, 3, 4]
b = a
a[:] = [x for x in a if x % 2]      # ✅ b ham o'zgardi
print(b)                            # [1, 3]

Lug'at va to'plam bilan — darhol xato:

python
lugat = {"a": 1, "b": 2}

for k in lugat:
    if lugat[k] == 1:
        del lugat[k]        # ❌ RuntimeError: dictionary changed size
python
# ✅ Nusxa bo'ylab
for k in list(lugat):
    if lugat[k] == 1:
        del lugat[k]

# ✅ Yoki yangi lug'at
lugat = {k: v for k, v in lugat.items() if v != 1}

Lug'at qiymatini o'zgartirish — MUMKIN:

python
for k in lugat:
    lugat[k] = lugat[k] * 2     # ✅ hajm o'zgarmaydi

Faqat hajm o'zgarishi taqiqlangan.

2.6. for / else

while/else bilan bir xil (5-dars):

python
for x in royxat:
    if x == qidiruv:
        print("Topildi")
        break
else:
    print("Topilmadi")      # break BO'LMASA bajariladi

Klassik qo'llanish — qidiruv:

python
def tub_sonmi(n: int) -> bool:
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True                     # else kerak emas — return bor

Bayroq o'zgaruvchisi kerak bo'lganda:

python
# ❌ Bayroq bilan
topildi = False
for x in royxat:
    if shart(x):
        topildi = True
        break

if not topildi:
    print("Topilmadi")

# ✅ else bilan
for x in royxat:
    if shart(x):
        break
else:
    print("Topilmadi")

Ichma-ich siklda:

python
for i in range(3):
    for j in range(3):
        if jadval[i][j] == qidiruv:
            print(f"Topildi: ({i}, {j})")
            break
    else:
        continue                    # ichki sikl break siz tugadi
    break                           # ichki sikl break bilan tugadi
else:
    print("Topilmadi")

Bu — chalkash. Yaxshiroq — funksiyaga o'rash:

python
def qidir(jadval, qidiruv):
    for i, qator in enumerate(jadval):
        for j, qiymat in enumerate(qator):
            if qiymat == qidiruv:
                return i, j
    return None

11-darsda ichma-ich sikllarni batafsil ko'ramiz.

2.7. Sikl o'zgaruvchilari va qamrov

Sikl o'zgaruvchisi funksiya qamrovida (7-qism):

python
def f():
    for i in range(3):
        pass
    print(i)                # 2 — funksiya ichida mavjud

Pythonda for yangi qamrov yaratmaydi (JavaScript'dagi let dan farqli).

Bu — yopilish (closure) tuzog'i:

python
funksiyalar = []
for i in range(3):
    funksiyalar.append(lambda: i)

print([f() for f in funksiyalar])   # [2, 2, 2] ← hammasi 2!

Barcha lambda bir xil i o'zgaruvchisiga ishora qiladi va sikl tugagach i = 2.

Yechim — sukut argument:

python
funksiyalar = []
for i in range(3):
    funksiyalar.append(lambda i=i: i)   # ← qiymat "muzlatiladi"

print([f() for f in funksiyalar])   # [0, 1, 2] ✅

Yoki functools.partial:

python
from functools import partial

funksiyalar = [partial(lambda x: x, i) for i in range(3)]

7 va 10-qismlarda batafsil.

Generatorlar boshqacha:

python
gen = (lambda: i for i in range(3))
print([f() for f in gen])           # [0, 1, 2] — generator har safar yangi

2.8. for vs while — qaror

for afzal (95% holatda):

python
for x in royxat: ...                # to'plam bo'ylab
for i in range(n): ...              # n marta
for k, v in lugat.items(): ...      # lug'at
for qator in fayl: ...              # fayl

while kerak:

python
while not tugadi(): ...             # shart bo'yicha
while True: ...                     # break bilan chiqish
while stek: ...                     # to'plam bo'shalguncha
while chap <= ong: ...              # ikkilik qidiruv

while ni for ga aylantirish:

python
# ❌ C uslubi
i = 0
while i < len(royxat):
    print(royxat[i])
    i += 1

# ✅ Python
for x in royxat:
    print(x)

# ✅ Indeks kerak bo'lsa
for i, x in enumerate(royxat):
    print(i, x)

# ✅ Faqat indeks kerak bo'lsa
for i in range(len(royxat)):
    print(i)

Tezlik:

python
import time

N = 500_000
royxat = list(range(N))

# for
boshlandi = time.perf_counter()
jami = 0
for x in royxat:
    jami += x
vaqt_for = time.perf_counter() - boshlandi

# while + indeks
boshlandi = time.perf_counter()
jami = 0
i = 0
while i < len(royxat):
    jami += royxat[i]
    i += 1
vaqt_while = time.perf_counter() - boshlandi

print(f"  for:   {vaqt_for * 1000:>7.1f} ms")
print(f"  while: {vaqt_while * 1000:>7.1f} ms")

for odatda 2-3 barobar tezroq.

2.9. Samaradorlik maslahatlari

1. range(len(x)) o'rniga enumerate:

python
for i in range(len(royxat)):        # ⚠️
    print(i, royxat[i])

for i, x in enumerate(royxat):      # ✅
    print(i, x)

2. Ikki ro'yxat — zip:

python
for i in range(len(a)):             # ⚠️
    print(a[i], b[i])

for x, y in zip(a, b):              # ✅
    print(x, y)

3. Lug'at — .items():

python
for k in lugat:                     # ⚠️ ikki qidiruv
    print(k, lugat[k])

for k, v in lugat.items():          # ✅
    print(k, v)

4. Siklda len() chaqirmang:

python
for i in range(len(royxat)):        # len bir marta chaqiriladi ✅
    ...

while i < len(royxat):              # ❌ har iteratsiyada
    ...

5. Ro'yxat generatorlari tezroq:

python
natija = []
for x in manba:
    natija.append(x * 2)            # ⚠️

natija = [x * 2 for x in manba]     # ✅ tezroq

6. Katta to'plamda generator:

python
# ❌ Butun ro'yxat xotirada
for x in [i * 2 for i in range(10_000_000)]:
    ...

# ✅ Generator — bir vaqtda bitta element
for x in (i * 2 for i in range(10_000_000)):
    ...

7. in tekshiruvi uchun set (3.11-dars):

python
for x in katta_royxat:
    if x in boshqa_royxat:          # ❌ O(n) har safar
        ...

boshqa_toplam = set(boshqa_royxat)  # ✅
for x in katta_royxat:
    if x in boshqa_toplam:          # O(1)
        ...

3. Tez ma'lumotnoma

Sintaksis

python
for <ozgaruvchi> in <iterable>:
    <blok>
else:                       # break BO'LMASA bajariladi
    <else_blok>

Iteratsiya protokoli

python
iter(x)         iterator olish
next(it)        keyingi element
next(it, sukut) xatosiz

Iterable  — __iter__ bor, qayta ishlatiladi
Iterator  — __iter__ va __next__, BIR MARTA

Ochish

python
for a, b in juftliklar: ...
for k, v in lugat.items(): ...
for i, x in enumerate(x): ...
for a, b in zip(x, y): ...
for ism, *ballar in qatorlar: ...
for _, v in juftliklar: ...

Iteratsiya paytida o'zgartirish

python
for x in royxat:
    royxat.remove(x)        ❌ elementlar o'tkazib yuboriladi

royxat[:] = [x for x in royxat if shart(x)]     ✅
for x in royxat[:]: ...                          ✅ nusxa
for k in list(lugat): ...                        ✅ lug'at uchun

Idiomatik

python
for x in royxat:                    ✅   for i in range(len(royxat)):  ⚠️
for i, x in enumerate(royxat):      ✅   royxat[i]                     ⚠️
for k, v in lugat.items():          ✅   for k in lugat: lugat[k]      ⚠️
for a, b in zip(x, y):              ✅   for i in range(len(x)):       ⚠️

4. Batafsil misollar

Misol 1 — Iteratsiya protokoli

python
"""for ichkarida qanday ishlaydi."""

print("=== 1. iter() va next() ===")

royxat = [10, 20, 30]
it = iter(royxat)

print(f"  iter([10,20,30]) → {type(it).__name__}")
print(f"  next(it) → {next(it)}")
print(f"  next(it) → {next(it)}")
print(f"  next(it) → {next(it)}")
try:
    next(it)
except StopIteration:
    print("  next(it) → StopIteration ✅")

print(f"\n  Sukut qiymat bilan:")
it = iter([1])
print(f"    next(it, 'tugadi') → {next(it, 'tugadi')}")
print(f"    next(it, 'tugadi') → {next(it, 'tugadi')}")


print("\n\n=== 2. for ni qo'lda amalga oshirish ===")


def mening_for(toplam, ishla):
    """for ning ichki mantiqini takrorlaydi."""
    iterator = iter(toplam)
    while True:
        try:
            element = next(iterator)
        except StopIteration:
            break
        ishla(element)


print("  for x in [1,2,3]: print(x)")
mening_for([1, 2, 3], lambda x: print(f"    {x}"))


print("\n\n=== 3. ⭐ Iterable vs Iterator ===")

royxat = [1, 2, 3]

print("  Iterable (list) — qayta ishlatiladi:")
print(f"    1-marta: {[x for x in royxat]}")
print(f"    2-marta: {[x for x in royxat]}  ✅")

it = iter(royxat)
print("\n  Iterator — BIR MARTA:")
print(f"    1-marta: {[x for x in it]}")
print(f"    2-marta: {[x for x in it]}  ← bo'sh!")

gen = (x * 2 for x in range(3))
print("\n  Generator ham iterator:")
print(f"    1-marta: {list(gen)}")
print(f"    2-marta: {list(gen)}  ← bo'sh!")


print("\n\n=== 4. Nima bo'ylab yurish mumkin ===")

from collections.abc import Iterable, Iterator

TEKSHIRUVLAR = [
    ("ro'yxat", [1, 2, 3]),
    ("juftlik", (1, 2, 3)),
    ("satr", "abc"),
    ("baytlar", b"abc"),
    ("to'plam", {1, 2, 3}),
    ("lug'at", {"a": 1}),
    ("range", range(3)),
    ("generator", (x for x in range(3))),
    ("iterator", iter([1, 2])),
    ("son", 42),
]

print(f"  {'Tur':<14} {'Iterable':>10} {'Iterator':>10} {'Elementlar'}")
print("  " + "─" * 58)

for nom, obyekt in TEKSHIRUVLAR:
    is_iterable = isinstance(obyekt, Iterable)
    is_iterator = isinstance(obyekt, Iterator)

    if is_iterable:
        # Generator/iteratorni buzmaslik uchun nusxa
        if is_iterator:
            elementlar = "(bir martalik)"
        else:
            elementlar = str(list(obyekt))[:20]
    else:
        elementlar = "❌ iteratsiya qilinmaydi"

    print(f"  {nom:<14} {is_iterable!s:>10} {is_iterator!s:>10} {elementlar}")


print("\n\n=== 5. O'z sinfingiz ===")


class Fibonachchi:
    """Fibonachchi sonlari — n tagacha."""

    def __init__(self, n: int):
        self.n = n

    def __iter__(self):
        a, b = 0, 1
        for _ in range(self.n):
            yield a
            a, b = b, a + b


fib = Fibonachchi(10)
print(f"  Fibonachchi(10): {list(fib)}")
print(f"  Qayta ishlatish: {list(fib)}  ← ✅ ishlaydi")
print("  (chunki __iter__ har safar yangi generator qaytaradi)")


class BirMartalik:
    """❌ Bir martalik — __iter__ self qaytaradi."""

    def __init__(self, n):
        self.n = n
        self.joriy = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.joriy >= self.n:
            raise StopIteration
        self.joriy += 1
        return self.joriy


bm = BirMartalik(3)
print(f"\n  BirMartalik(3): {list(bm)}")
print(f"  Qayta ishlatish: {list(bm)}  ← ❌ bo'sh")

Natijaning muhim qismi:

text
=== 3. ⭐ Iterable vs Iterator ===
  Iterable (list) — qayta ishlatiladi:
    1-marta: [1, 2, 3]
    2-marta: [1, 2, 3]  ✅

  Iterator — BIR MARTA:
    1-marta: [1, 2, 3]
    2-marta: []  ← bo'sh!

=== 4. Nima bo'ylab yurish mumkin ===
  Tur              Iterable   Iterator Elementlar
  ──────────────────────────────────────────────────────────
  ro'yxat              True      False [1, 2, 3]
  juftlik              True      False [1, 2, 3]
  satr                 True      False ['a', 'b', 'c']
  baytlar              True      False [97, 98, 99]
  to'plam              True      False [1, 2, 3]
  lug'at               True      False ['a']
  range                True      False [0, 1, 2]
  generator            True       True (bir martalik)
  iterator             True       True (bir martalik)
  son                 False      False ❌ iteratsiya qilinmaydi

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

Misol 2 — Iteratsiya paytida o'zgartirish

python
"""Klassik tuzoq va uning yechimlari."""

print("=== 1. ❌ Muammo ===")

royxat = [1, 2, 2, 3, 4, 4, 5]
asl = royxat[:]

print(f"  Asl:     {asl}")
print("  Maqsad:  juft sonlarni o'chirish → [1, 3, 5]\n")

for x in royxat:
    if x % 2 == 0:
        royxat.remove(x)

print(f"  Natija:  {royxat}  ← ❌ ba'zi juftlar qoldi!")


print("\n\n=== 2. Nima bo'lyapti — qadam-baqadam ===")

royxat = [1, 2, 2, 3, 4, 4, 5]
i = 0

print(f"  {'Indeks':>7} {'Element':>8} {'Amal':<12} {'Roʻyxat'}")
print("  " + "─" * 50)

# Iteratsiyani qo'lda simulyatsiya qilamiz
indeks = 0
while indeks < len(royxat):
    x = royxat[indeks]
    if x % 2 == 0:
        royxat.remove(x)
        amal = "o'chirildi"
        # remove dan keyin indeks OSHMAYDI (element siljidi)
    else:
        amal = "qoldirildi"
        indeks += 1
    print(f"  {indeks:>7} {x:>8} {amal:<12} {royxat}")

print("\n  Haqiqiy for da indeks HAR DOIM oshadi — shuning uchun")
print("  o'chirishdan keyin keyingi element O'TKAZIB YUBORILADI.")


print("\n\n=== 3. ✅ Beshta yechim ===")

USULLAR = {}


def usul_1(x):
    """Yangi ro'yxat (eng idiomatik)."""
    return [e for e in x if e % 2 != 0]


def usul_2(x):
    """Nusxa bo'ylab yurish."""
    natija = x[:]
    for e in x[:]:
        if e % 2 == 0:
            natija.remove(e)
    return natija


def usul_3(x):
    """Teskari yo'nalishda."""
    natija = x[:]
    for i in range(len(natija) - 1, -1, -1):
        if natija[i] % 2 == 0:
            del natija[i]
    return natija


def usul_4(x):
    """filter."""
    return list(filter(lambda e: e % 2 != 0, x))


def usul_5(x):
    """Joyida almashtirish (havolani saqlaydi)."""
    natija = x[:]
    natija[:] = [e for e in natija if e % 2 != 0]
    return natija


ASL = [1, 2, 2, 3, 4, 4, 5]
KUTILGAN = [1, 3, 5]

for nom, f in [("Ro'yxat generatori", usul_1), ("Nusxa bo'ylab", usul_2),
               ("Teskari yo'nalish", usul_3), ("filter", usul_4),
               ("Joyida [:]", usul_5)]:
    natija = f(ASL[:])
    belgi = "✅" if natija == KUTILGAN else "❌"
    print(f"  {belgi} {nom:<22} → {natija}")


print("\n\n=== 4. ⭐ Nega [:] muhim ===")

a = [1, 2, 3, 4]
b = a
print(f"  a = {a}, b = a (bir xil obyekt: {a is b})")

a = [x for x in a if x % 2]
print(f"\n  a = [x for x in a if x % 2]")
print(f"    a = {a}")
print(f"    b = {b}  ← ❌ b o'zgarmadi")

a = [1, 2, 3, 4]
b = a
a[:] = [x for x in a if x % 2]
print(f"\n  a[:] = [x for x in a if x % 2]")
print(f"    a = {a}")
print(f"    b = {b}  ← ✅ b ham o'zgardi")

print("\n  (3.1-dars: yorliq modeli)")


print("\n\n=== 5. Lug'at va to'plam ===")

lugat = {"a": 1, "b": 2, "c": 1}
print(f"  Lug'at: {lugat}")

print("\n  ❌ Iteratsiya paytida o'chirish:")
try:
    for k in lugat:
        if lugat[k] == 1:
            del lugat[k]
except RuntimeError as x:
    print(f"    RuntimeError: {x}")

lugat = {"a": 1, "b": 2, "c": 1}
print("\n  ✅ list(lugat) bo'ylab:")
for k in list(lugat):
    if lugat[k] == 1:
        del lugat[k]
print(f"    Natija: {lugat}")

lugat = {"a": 1, "b": 2, "c": 1}
print("\n  ✅ Yangi lug'at:")
lugat = {k: v for k, v in lugat.items() if v != 1}
print(f"    Natija: {lugat}")

lugat = {"a": 1, "b": 2}
print("\n  ✅ Qiymatni o'zgartirish — MUMKIN (hajm o'zgarmaydi):")
for k in lugat:
    lugat[k] *= 10
print(f"    Natija: {lugat}")


print("\n\n=== 6. To'plam ===")

toplam = {1, 2, 3, 4}
print(f"  To'plam: {toplam}")

print("\n  ❌ Iteratsiya paytida:")
try:
    for x in toplam:
        if x % 2 == 0:
            toplam.discard(x)
except RuntimeError as x:
    print(f"    RuntimeError: {x}")

toplam = {1, 2, 3, 4}
print("\n  ✅ To'plam generatori:")
toplam = {x for x in toplam if x % 2 != 0}
print(f"    Natija: {toplam}")

Natijaning muhim qismi:

text
=== 1. ❌ Muammo ===
  Asl:     [1, 2, 2, 3, 4, 4, 5]
  Maqsad:  juft sonlarni o'chirish → [1, 3, 5]

  Natija:  [1, 2, 3, 4, 5]  ← ❌ ba'zi juftlar qoldi!

=== 5. Lug'at va to'plam ===
  Lug'at: {'a': 1, 'b': 2, 'c': 1}

  ❌ Iteratsiya paytida o'chirish:
    RuntimeError: dictionary changed size during iteration

  ✅ list(lugat) bo'ylab:
    Natija: {'b': 2}

Nima ko'rsatdi: 2.5-bo'lim.

Misol 3 — Ochish va idiomatik yozuv

python
"""for da ochish — Pythonning eng qulay imkoniyati."""

from dataclasses import dataclass

print("=== 1. Juftliklar ===")

juftliklar = [(1, "bir"), (2, "ikki"), (3, "uch")]

print("  ❌ Indeks bilan:")
for j in juftliklar:
    print(f"    {j[0]} = {j[1]}")

print("\n  ✅ Ochish bilan:")
for son, nom in juftliklar:
    print(f"    {son} = {nom}")


print("\n\n=== 2. Lug'at ===")

lugat = {"ism": "Ali", "yosh": 25, "shahar": "Toshkent"}

print("  ❌ Ikki qidiruv:")
for k in lugat:
    print(f"    {k}: {lugat[k]}")

print("\n  ✅ .items() bilan:")
for k, v in lugat.items():
    print(f"    {k}: {v}")

print(f"\n  ⚠️ `for k in lugat` KALITLARNI beradi: {list(lugat)}")
print(f"     Qiymatlar uchun: {list(lugat.values())}")


print("\n\n=== 3. Ichma-ich ochish ===")

malumot = [
    ("Ali", (25, "Toshkent", "dasturchi")),
    ("Vali", (30, "Samarqand", "muhandis")),
]

for ism, (yosh, shahar, kasb) in malumot:
    print(f"  {ism:<8} {yosh} yosh, {shahar}, {kasb}")


print("\n\n=== 4. Yulduzcha bilan ===")

QATORLAR = [
    ["Ali", 85, 90, 78, 92],
    ["Vali", 92, 88, 95],
    ["Guli", 79, 85],
]

print(f"  {'Ism':<8} {'Ballar':<20} {'Soni':>5} {'Oʻrtacha':>9}")
print("  " + "─" * 46)

for ism, *ballar in QATORLAR:
    ortacha = sum(ballar) / len(ballar) if ballar else 0
    print(f"  {ism:<8} {str(ballar):<20} {len(ballar):>5} {ortacha:>9.1f}")

print("\n  Boshqa shakllar:")
qator = ["Ali", 85, 90, 78, 92]
birinchi, *orta, oxirgi = qator
print(f"    birinchi, *orta, oxirgi = {birinchi!r}, {orta}, {oxirgi}")

*bosh, oxirgi = qator
print(f"    *bosh, oxirgi           = {bosh}, {oxirgi}")


print("\n\n=== 5. `_` — kerak emas qiymat ===")

print("  Faqat qiymatlar kerak:")
for _, qiymat in juftliklar:
    print(f"    {qiymat}")

print("\n  Faqat takrorlash kerak:")
for _ in range(3):
    print("    Salom")

print("\n  O'rtadagi qiymat kerak emas:")
uchliklar = [(1, 2, 3), (4, 5, 6)]
for a, _, c in uchliklar:
    print(f"    a={a}, c={c}")


print("\n\n=== 6. Amaliy: hisobot ===")


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


XODIMLAR = [
    Xodim("Ali Valiyev", "IT", 12_000_000, 28),
    Xodim("Sarvarbek Karimov", "IT", 15_000_000, 32),
    Xodim("Aziza Rahimova", "Moliya", 11_000_000, 26),
    Xodim("Bekzod Toshmatov", "Moliya", 13_500_000, 41),
    Xodim("Dilnoza Yusupova", "HR", 9_500_000, 24),
]

# Bo'limlar bo'yicha guruhlash
from collections import defaultdict

bolimlar = defaultdict(list)
for x in XODIMLAR:
    bolimlar[x.bolim].append(x)

print(f"  {'Boʻlim':<10} {'Soni':>5} {'Jami maosh':>16} {'Oʻrtacha':>16}")
print("  " + "─" * 52)

for bolim, xodimlar in sorted(bolimlar.items()):
    jami = sum(x.maosh for x in xodimlar)
    ortacha = jami / len(xodimlar)
    print(f"  {bolim:<10} {len(xodimlar):>5} {jami:>16,} {ortacha:>16,.0f}")

jami_hammasi = sum(x.maosh for x in XODIMLAR)
print("  " + "─" * 52)
print(f"  {'JAMI':<10} {len(XODIMLAR):>5} {jami_hammasi:>16,} "
      f"{jami_hammasi / len(XODIMLAR):>16,.0f}")


print("\n\n=== 7. Idiomatik yozuv ===")

a = [1, 2, 3]
b = ["x", "y", "z"]

print("  ❌ Noidiomatik              ✅ Idiomatik")
print("  " + "─" * 56)
almashtirishlar = [
    ("for i in range(len(a)):",     "for x in a:"),
    ("    print(a[i])",             "    print(x)"),
    ("",                            ""),
    ("for i in range(len(a)):",     "for i, x in enumerate(a):"),
    ("    print(i, a[i])",          "    print(i, x)"),
    ("",                            ""),
    ("for i in range(len(a)):",     "for x, y in zip(a, b):"),
    ("    print(a[i], b[i])",       "    print(x, y)"),
    ("",                            ""),
    ("for k in d:",                 "for k, v in d.items():"),
    ("    print(k, d[k])",          "    print(k, v)"),
]

for yomon, yaxshi in almashtirishlar:
    print(f"  {yomon:<28} {yaxshi}")

Natijaning muhim qismi:

text
=== 4. Yulduzcha bilan ===
  Ism      Ballar                Soni  Oʻrtacha
  ──────────────────────────────────────────────
  Ali      [85, 90, 78, 92]         4      86.2
  Vali     [92, 88, 95]             3      91.7
  Guli     [79, 85]                 2      82.0

  Boshqa shakllar:
    birinchi, *orta, oxirgi = 'Ali', [85, 90, 78], 92
    *bosh, oxirgi           = ['Ali', 85, 90, 78], 92

=== 6. Amaliy: hisobot ===
  Boʻlim      Soni       Jami maosh         Oʻrtacha
  ────────────────────────────────────────────────────
  HR            1        9,500,000        9,500,000
  IT            2       27,000,000       13,500,000
  Moliya        2       24,500,000       12,250,000
  ────────────────────────────────────────────────────
  JAMI          5       61,000,000       12,200,000

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

Misol 4 — Yopilish tuzog'i va tezlik

python
"""for o'zgaruvchisi va qamrov."""

import time
from functools import partial

print("=== 1. ⭐ Yopilish (closure) tuzog'i ===")

print("  ❌ Muammo:")
funksiyalar = []
for i in range(3):
    funksiyalar.append(lambda: i)

natijalar = [f() for f in funksiyalar]
print(f"    [lambda: i for i in range(3)] → {natijalar}")
print("    ← Hammasi 2! Barcha lambda BIR XIL i ga ishora qiladi")

print("\n  ✅ Sukut argument bilan:")
funksiyalar = []
for i in range(3):
    funksiyalar.append(lambda i=i: i)

print(f"    [lambda i=i: i for i in range(3)] → {[f() for f in funksiyalar]}")

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

print("\n  ✅ Funksiya fabrikasi bilan:")


def yaratuvchi(qiymat):
    def ichki():
        return qiymat
    return ichki


funksiyalar = [yaratuvchi(i) for i in range(3)]
print(f"    fabrika bilan → {[f() for f in funksiyalar]}")

print("\n  Nima uchun bunday: 7-qism (LEGB qoidasi)")


print("\n\n=== 2. Sikl o'zgaruvchisi sikldan keyin ===")

for i in range(3):
    pass
print(f"  Sikldan keyin i = {i}")

for x in []:
    pass
try:
    print(x)
except NameError:
    print("  Bo'sh to'plamda o'zgaruvchi YARATILMAYDI (NameError)")

print("\n  ✅ Xavfsiz naqsh:")
oxirgi = None
for oxirgi in [1, 2, 3]:
    pass
print(f"    oxirgi = {oxirgi}")

oxirgi = None
for oxirgi in []:
    pass
print(f"    bo'sh ro'yxatda: oxirgi = {oxirgi}")


print("\n\n=== 3. Sikl o'zgaruvchisini o'zgartirish ===")

print("  for i in range(3): i = 100")
for i in range(3):
    i = 100
    print(f"    i = {i}", end="")
print()
print("  ← Har iteratsiyada QAYTA o'zlashtiriladi — ta'sir yo'q")


print("\n\n=== 4. Tezlik: for vs while ===")

N = 300_000
royxat = list(range(N))

# for
boshlandi = time.perf_counter()
jami1 = 0
for x in royxat:
    jami1 += x
vaqt_for = time.perf_counter() - boshlandi

# while + indeks
boshlandi = time.perf_counter()
jami2 = 0
i = 0
n = len(royxat)
while i < n:
    jami2 += royxat[i]
    i += 1
vaqt_while = time.perf_counter() - boshlandi

# for + range(len())
boshlandi = time.perf_counter()
jami3 = 0
for i in range(len(royxat)):
    jami3 += royxat[i]
vaqt_range = time.perf_counter() - boshlandi

# enumerate
boshlandi = time.perf_counter()
jami4 = 0
for i, x in enumerate(royxat):
    jami4 += x
vaqt_enum = time.perf_counter() - boshlandi

# sum()
boshlandi = time.perf_counter()
jami5 = sum(royxat)
vaqt_sum = time.perf_counter() - boshlandi

assert jami1 == jami2 == jami3 == jami4 == jami5

natijalar = [
    ("sum()", vaqt_sum),
    ("for x in royxat", vaqt_for),
    ("for i, x in enumerate", vaqt_enum),
    ("for i in range(len())", vaqt_range),
    ("while + indeks", vaqt_while),
]

eng_tez = min(v for _, v in natijalar)
print(f"  {'Usul':<24} {'Vaqt':>9} {'Nisbat':>8}")
print("  " + "─" * 44)
for nom, vaqt in sorted(natijalar, key=lambda x: x[1]):
    print(f"  {nom:<24} {vaqt * 1000:>6.1f} ms {vaqt / eng_tez:>7.1f}x")


print("\n\n=== 5. Ro'yxat generatori vs sikl ===")

N = 200_000

boshlandi = time.perf_counter()
natija1 = []
for x in range(N):
    natija1.append(x * 2)
vaqt_append = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
natija2 = [x * 2 for x in range(N)]
vaqt_comp = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
natija3 = list(map(lambda x: x * 2, range(N)))
vaqt_map = time.perf_counter() - boshlandi

assert natija1 == natija2 == natija3

print(f"  for + append:       {vaqt_append * 1000:>7.1f} ms")
print(f"  ro'yxat generatori: {vaqt_comp * 1000:>7.1f} ms  "
      f"({vaqt_append / vaqt_comp:.1f}x tezroq)")
print(f"  map + lambda:       {vaqt_map * 1000:>7.1f} ms")


print("\n\n=== 6. `in` tekshiruvi (3.11-dars) ===")

KATTA = list(range(50_000))
QIDIRUV = list(range(0, 50_000, 100))

boshlandi = time.perf_counter()
topilgan1 = [x for x in QIDIRUV if x in KATTA]
vaqt_royxat = time.perf_counter() - boshlandi

KATTA_SET = set(KATTA)
boshlandi = time.perf_counter()
topilgan2 = [x for x in QIDIRUV if x in KATTA_SET]
vaqt_set = time.perf_counter() - boshlandi

assert topilgan1 == topilgan2

print(f"  {len(QIDIRUV)} ta qidiruv, {len(KATTA):,} elementli konteynerda:")
print(f"    ro'yxatda: {vaqt_royxat * 1000:>8.1f} ms   O(n)")
print(f"    to'plamda: {vaqt_set * 1000:>8.3f} ms   O(1)")
print(f"    Tezlik farqi: {vaqt_royxat / vaqt_set:,.0f}x")

Natijaning muhim qismi:

text
=== 1. ⭐ Yopilish (closure) tuzog'i ===
  ❌ Muammo:
    [lambda: i for i in range(3)] → [2, 2, 2]
    ← Hammasi 2! Barcha lambda BIR XIL i ga ishora qiladi

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

=== 4. Tezlik: for vs while ===
  Usul                          Vaqt   Nisbat
  ────────────────────────────────────────────
  sum()                          2.1 ms     1.0x
  for x in royxat               11.8 ms     5.6x
  for i, x in enumerate         14.2 ms     6.8x
  for i in range(len())         18.7 ms     8.9x
  while + indeks                24.3 ms    11.6x

=== 6. `in` tekshiruvi (3.11-dars) ===
  500 ta qidiruv, 50,000 elementli konteynerda:
    ro'yxatda:    847.3 ms   O(n)
    to'plamda:      0.052 ms   O(1)
    Tezlik farqi: 16,294x

Nima ko'rsatdi: 2.7, 2.8, 2.9-bo'limlar.


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

Noto'g'ri fikr To'g'risi
"for — hisoblagichli sikl" To'plam bo'ylab yurish. Hisoblagich uchun range
"for k in lugat qiymatlarni beradi" Kalitlarni. Qiymat uchun .values()
"Iteratsiya paytida o'chirish mumkin" Elementlar o'tkazib yuboriladi. Lug'atda — RuntimeError
"Generator qayta ishlatiladi" Bir martalik. Ikkinchi marta bo'sh
"for yangi qamrov yaratadi" Yo'q — o'zgaruvchi sikldan keyin ham mavjud
"lambda: i har safar yangi i" Barchasi bir xil o'zgaruvchiga ishora qiladi
"for va while bir xil tez" for 2-3 barobar tezroq
"range(len(x)) normal" enumerate idiomatik va tezroq

6. Keng tarqalgan xatolar va yechimlari

1. Iteratsiya paytida o'zgartirish

python
for x in royxat:
    royxat.remove(x)                    # ❌

royxat[:] = [x for x in royxat if shart(x)]     # ✅

2. Lug'at hajmini o'zgartirish

python
for k in lugat:
    del lugat[k]                        # ❌ RuntimeError

for k in list(lugat):                   # ✅
    del lugat[k]

3. Generatorni qayta ishlatish

python
gen = (x for x in range(3))
print(list(gen))                        # [0, 1, 2]
print(list(gen))                        # ❌ []

royxat = list(gen)                      # ✅ bir marta ro'yxatga

4. range(len(x))

python
for i in range(len(royxat)):            # ⚠️
    print(i, royxat[i])

for i, x in enumerate(royxat):          # ✅
    print(i, x)

5. Yopilish tuzog'i

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

6. Bo'sh to'plamda o'zgaruvchi

python
for x in []:
    pass
print(x)                                # ❌ NameError

x = None                                # ✅
for x in []:
    pass

7. Ochish uzunligi mos emas

python
for a, b in [(1, 2), (3, 4, 5)]:        # ❌ ValueError
    ...

for a, b, *qolgani in malumot:          # ✅ moslashuvchan
    ...

8. in uchun ro'yxat

python
for x in katta:
    if x in boshqa_royxat:              # ❌ O(n)
        ...

boshqa = set(boshqa_royxat)             # ✅ O(1)
for x in katta:
    if x in boshqa:
        ...

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 5.7-dars: range() chuqur
  • 5.8-dars: enumerate()
  • 5.9-dars: zip()
  • 5.10-dars: break, continue, for/else
  • 5.11-dars: ichma-ich sikllar
  • 6-qism: ro'yxat/lug'at/to'plam generatorlari
  • 10, 15-qismlar: generatorlar, yield, itertools
  • 10-qism: __iter__, __next__ — o'z sinflaringiz
  • Har bir dasturda: eng ko'p ishlatiladigan tuzilma

8. Eng yaxshi amaliyotlar

  1. To'plam bo'ylab to'g'ridan-to'g'ri yuring. for x in royxat: — range(len()) emas.

  2. Iteratsiya paytida to'plamni o'zgartirmang. Yangi to'plam yarating yoki nusxa bo'ylab yuring.

  3. Lug'at uchun .items(). Ikki qidiruv o'rniga bitta.

  4. Ochishdan foydalaning. for k, v in ..., for i, x in enumerate(...).

  5. Generatorlar bir martalik ekanini eslang. Qayta kerak bo'lsa — ro'yxatga aylantiring.

  6. lambda da sukut argument. Yopilish tuzog'idan qutuling.

  7. Katta to'plamda generator ishlating. Xotira tejaydi.

  8. in tekshiruvi uchun set. Sikl ichida ro'yxatda qidirish — O(n²).


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
1.  for i in range(3): pass
    print(i)

2.  for x in []: pass
    print(x)

3.  d = {"a": 1, "b": 2}
    for k in d: print(k, end=" ")

4.  for x in "abc": print(x, end=" ")

5.  for b in b"abc": print(b, end=" ")

6.  g = (x for x in range(3))
    print(list(g), list(g))

7.  f = [lambda: i for i in range(3)]
    print([x() for x in f])

8.  r = [1, 2, 3, 4]
    for x in r:
        if x % 2 == 0:
            r.remove(x)
    print(r)
Javoblar
  1. 2
  2. NameError
  3. a b — kalitlar
  4. a b c
  5. 97 98 99 — sonlar!
  6. [0, 1, 2] []
  7. [2, 2, 2]
  8. [1, 3] — bu holda tasodifan to'g'ri

Vazifa 2: Idiomatik qiling

python
1.  for i in range(len(royxat)):
        print(royxat[i])

2.  for i in range(len(a)):
        print(a[i], b[i])

3.  for k in lugat:
        print(k, lugat[k])

4.  i = 0
    while i < len(royxat):
        print(i, royxat[i])
        i += 1

5.  natija = []
    for x in manba:
        natija.append(x * 2)
Javoblar
python
1.  for x in royxat: print(x)
2.  for x, y in zip(a, b): print(x, y)
3.  for k, v in lugat.items(): print(k, v)
4.  for i, x in enumerate(royxat): print(i, x)
5.  natija = [x * 2 for x in manba]

Vazifa 3: O'chirish

royxat = [1, 2, 2, 3, 4, 4, 5, 6] dan juft sonlarni o'chiring — besh usulda. Har birini sinang va natijani solishtiring.

Vazifa 4: O'z iteratorlaringiz

Sinflar yarating:

  1. Diapazon(boshi, oxiri, qadam) — range ga o'xshash
  2. Aylanma(royxat, marta) — ro'yxatni marta marta takrorlaydi
  3. Juftliklar(royxat) — ketma-ket juftliklarni beradi: [1,2,3] → (1,2), (2,3)

Har birini qayta ishlatiladigan qiling.

Yechim (3-vazifa)
python
class Juftliklar:
    def __init__(self, royxat):
        self.royxat = royxat

    def __iter__(self):
        for i in range(len(self.royxat) - 1):
            yield self.royxat[i], self.royxat[i + 1]


j = Juftliklar([1, 2, 3, 4])
print(list(j))          # [(1, 2), (2, 3), (3, 4)]
print(list(j))          # ✅ qayta ishlaydi

itertools.pairwise — tayyor variant (Python 3.10+).

Vazifa 5: Yopilish tuzog'i

python
tugmalar = []
for nom in ["Saqlash", "O'chirish", "Bekor"]:
    tugmalar.append(lambda: print(f"Bosildi: {nom}"))

for t in tugmalar:
    t()
  1. Nima chiqadi?
  2. Nega?
  3. Uch usulda tuzating

Vazifa 6: Hisobot

3-misoldagi xodimlar hisobotini kengaytiring:

  1. Yosh guruhlari bo'yicha statistika
  2. Eng yuqori/past maoshli xodim
  3. Bo'lim ichida maosh bo'yicha saralash
  4. Umumiy fondda har bo'lim ulushi (foizda)

Vazifa 7: O'ylash

Nega Pythonda C uslubidagi for (i = 0; i < n; i++) yo'q?

Javob

Chunki u kam kerak va xatoga moyil.

1. Ko'p holatda indeks kerak emas.

c
for (int i = 0; i < len; i++) {
    printf("%d\n", arr[i]);     // i faqat elementga yetish uchun
}
python
for x in royxat:                # ✅ to'g'ridan-to'g'ri element
    print(x)

2. Indeks — xato manbai:

c
for (int i = 0; i <= len; i++)  // ❌ bir qadam ortiqcha
for (int i = 1; i < len; i++)   // ❌ birinchi element o'tkazildi

Bu — "off-by-one" xatolari, dasturlashdagi eng keng tarqalgan xato turi.

3. Iteratsiya protokoli universalroq.

C uslubidagi for faqat indekslanadigan to'plamlar bilan ishlaydi. Python for esa:

  • Fayllar (indeks yo'q)
  • Generatorlar (uzunlik noma'lum)
  • Lug'atlar
  • Cheksiz ketma-ketliklar (itertools.count())
  • Tarmoq oqimlari

4. Indeks kerak bo'lganda — enumerate bor:

python
for i, x in enumerate(royxat):
    print(i, x)

Bu — C uslubidan aniqroq va xatosiz.

Solishtiring: Go va Rust ham shu yo'lni tanladi:

go
for i, v := range royxat { ... }        // Go
rust
for (i, v) in royxat.iter().enumerate() { ... }   // Rust

Zamonaviy tillar iteratsiya protokolini afzal ko'radi.

Nimani mustahkamlaydi: 2.2, 2.4, 2.5, 2.7, 2.9-bo'limlar.


Xulosa

Bu darsda for siklini o'rgandik.

Eng muhim uch fikr:

  1. for — iteratsiya protokoliga asoslangan. U iter() bilan iterator oladi va next() bilan elementlarni beradi. Shuning uchun ro'yxat, satr, fayl, generator va o'z sinfingiz bilan bir xil ishlaydi.

  2. Iteratsiya paytida to'plamni o'zgartirmang. Ro'yxatda elementlar jimgina o'tkazib yuboriladi, lug'at va to'plamda RuntimeError. Yangi to'plam yarating yoki nusxa bo'ylab yuring.

  3. Ochishdan foydalaning. for k, v in lugat.items(), for i, x in enumerate(royxat), for ism, *ballar in qatorlar — bu Pythonning eng qulay imkoniyatlaridan biri va u kodni ancha o'qiladigan qiladi.

Keyingi darsda range() ni chuqur o'rganamiz: u qanday ishlaydi, nega ro'yxat emas, manfiy qadam va eng ko'p uchraydigan xatolar.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.6-dars: for sikli — IlmHamroh