IlmHamroh
Python kursi/Boshqaruv oqimi8/12-dars25 daqiqa
Mundarija (23)

5.8-dars: enumerate()

5-QISM — BOSHQARUV OQIMI · 8-dars


1. Kirish va motivatsiya

Sikl ichida indeks ham, element ham kerak bo'lgan holat juda ko'p uchraydi:

text
"3-qatorda xato"
"1. Birinchi punkt"
"Element #5 topildi"

Boshqa tillardan kelganlar odatda shunday yozadi:

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

Bu ishlaydi, lekin Pythonda noidiomatik. To'g'ri usul:

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

Farq faqat estetik emas:

  • Tezroq — indeksga murojaat yo'q
  • Xavfsizroq — off-by-one xatolari kamayadi
  • Universalroq — len() bo'lmagan obyektlar bilan ham ishlaydi

Va enumerate ning bir necha kam ma'lum imkoniyati bor:

python
enumerate(royxat, start=1)          # 1 dan boshlash
list(enumerate("abc"))              # [(0,'a'), (1,'b'), (2,'c')]
dict(enumerate(royxat))             # {0: 'a', 1: 'b'}

Bu darsda hammasini o'rganamiz.


2. Nazariya — chuqur tushuntirish

2.1. Asosiy foydalanish

python
mevalar = ["olma", "anor", "uzum"]

for i, meva in enumerate(mevalar):
    print(f"{i}: {meva}")
text
0: olma
1: anor
2: uzum

enumerate juftliklar generatorini qaytaradi:

python
e = enumerate(mevalar)
print(type(e))                      # <class 'enumerate'>
print(list(e))                      # [(0, 'olma'), (1, 'anor'), (2, 'uzum')]

Ochish bilan (6-dars):

python
for juftlik in enumerate(mevalar):
    print(juftlik)                  # (0, 'olma')
    print(juftlik[0], juftlik[1])   # noqulay

for i, meva in enumerate(mevalar):  # ✅ ochish
    print(i, meva)

2.2. start parametri

python
for i, meva in enumerate(mevalar, start=1):
    print(f"{i}. {meva}")
text
1. olma
2. anor
3. uzum

Pozitsion ham berish mumkin:

python
enumerate(mevalar, 1)               # start=1 bilan bir xil

Har qanday boshlang'ich:

python
for i, x in enumerate("abc", 100):
    print(i, x)                     # 100 a / 101 b / 102 c

for i, x in enumerate("abc", -1):
    print(i, x)                     # -1 a / 0 b / 1 c

start — qadam emas:

python
enumerate(x, 2)                     # 2, 3, 4, ... (qadam 1)

Qadam kerak bo'lsa:

python
for i, x in zip(range(0, 100, 10), royxat):     # 0, 10, 20, ...
    print(i, x)

for i, x in enumerate(royxat):
    print(i * 10, x)                             # yoki shunday

Amaliy foydalanish:

python
# Foydalanuvchiga ko'rsatish — 1 dan
for i, punkt in enumerate(menyu, 1):
    print(f"  {i}. {punkt}")

# Fayl qatorlari — 1 dan
with open("fayl.txt", encoding="utf-8") as f:
    for raqam, qator in enumerate(f, 1):
        if xato(qator):
            print(f"{raqam}-qatorda xato")

2.3. enumerate qanday ishlaydi

enumerate — iterator (6-dars):

python
e = enumerate("abc")
print(next(e))                      # (0, 'a')
print(next(e))                      # (1, 'b')
print(next(e))                      # (2, 'c')
# print(next(e))                    # ❌ StopIteration

Bir martalik:

python
e = enumerate("abc")
print(list(e))                      # [(0, 'a'), (1, 'b'), (2, 'c')]
print(list(e))                      # []  ← bo'sh!

Sof Python ekvivalenti:

python
def mening_enumerate(iterable, start=0):
    n = start
    for element in iterable:
        yield n, element
        n += 1

Muhim: enumerate har qanday iteratsiya qilinadigan obyekt bilan ishlaydi — len() shart emas:

python
# ✅ len() bo'lmagan obyektlar
for i, qator in enumerate(fayl): ...
for i, x in enumerate(generator()): ...
for i, x in enumerate(itertools.count()): ...   # cheksiz!

range(len(x)) esa faqat len() bor obyektlar bilan ishlaydi.

Dangasa hisoblash:

python
from itertools import count, islice

# Cheksiz ketma-ketlikda ham ishlaydi
for i, x in enumerate(count(100, 5)):
    if i >= 3:
        break
    print(i, x)                     # 0 100 / 1 105 / 2 110

2.4. enumerate vs range(len())

python
royxat = ["a", "b", "c"]

# ❌ Noidiomatik
for i in range(len(royxat)):
    print(i, royxat[i])

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

Solishtirish:

range(len(x)) enumerate(x)
len() kerakmi Ha Yo'q
Indeksga murojaat Har iteratsiyada Yo'q
Tezlik Sekinroq Tezroq
Generatorlar bilan
Fayllar bilan
O'qish Yomonroq Yaxshiroq

Tezlik:

python
import time

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

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

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

print(f"  range(len()): {vaqt_range * 1000:>7.1f} ms")
print(f"  enumerate():  {vaqt_enum * 1000:>7.1f} ms")

Lekin indeks kerak bo'lmasa — ikkalasi ham ortiqcha:

python
for x in royxat:                    # ✅ eng tez
    ...

range(len()) qachon to'g'ri:

python
# 1. Elementni O'ZGARTIRISH
for i in range(len(royxat)):
    royxat[i] *= 2                  # ✅

# enumerate bilan ishlamaydi:
for i, x in enumerate(royxat):
    x *= 2                          # ❌ mahalliy nusxa

for i, x in enumerate(royxat):
    royxat[i] = x * 2               # ✅ lekin range oddiyroq

# 2. Faqat indeks kerak
for i in range(len(royxat)):
    print(i)                        # ✅

# 3. Indeks bilan murakkab ish
for i in range(len(royxat) - 1):
    print(royxat[i], royxat[i + 1])

Ruff: C0200 (pylint), lekin bu holatlarni ajratadi.

2.5. enumerate bilan naqshlar

1. Raqamlangan ro'yxat:

python
for i, punkt in enumerate(punktlar, 1):
    print(f"{i}. {punkt}")

2. Fayl qatorlari:

python
with open("fayl.txt", encoding="utf-8") as f:
    for raqam, qator in enumerate(f, 1):
        print(f"{raqam:>4} | {qator.rstrip()}")

3. Indeks topish:

python
# ❌ Ikki o'tish
if qidiruv in royxat:
    indeks = royxat.index(qidiruv)

# ✅ Bir o'tish
for i, x in enumerate(royxat):
    if x == qidiruv:
        indeks = i
        break
else:
    indeks = -1

# ✅ Generator bilan (10-qism)
indeks = next((i for i, x in enumerate(royxat) if x == qidiruv), -1)

4. Barcha mos indekslar:

python
indekslar = [i for i, x in enumerate(royxat) if shart(x)]

5. Lug'at yaratish:

python
# Element → indeks
indeks_lugat = {x: i for i, x in enumerate(royxat)}

# Indeks → element
element_lugat = dict(enumerate(royxat))

# 1 dan boshlab
raqamlangan = dict(enumerate(royxat, 1))

6. Har n-elementni ishlash:

python
for i, x in enumerate(royxat):
    if i % 3 == 0:
        ishla(x)

# Yoki kesim bilan (tezroq)
for x in royxat[::3]:
    ishla(x)

7. Birinchi/oxirgi elementni ajratish:

python
n = len(royxat)
for i, x in enumerate(royxat):
    if i == 0:
        print(f"Birinchi: {x}")
    elif i == n - 1:
        print(f"Oxirgi: {x}")
    else:
        print(f"O'rtada: {x}")

8. Ajratgich bilan chiqarish:

python
for i, x in enumerate(royxat):
    if i > 0:
        print(", ", end="")
    print(x, end="")
print()

# Yoki join (4.5-dars) — soddaroq
print(", ".join(map(str, royxat)))

2.6. enumerate va zip birga

9-darsda zip ni batafsil ko'ramiz. Ular birga tez-tez ishlatiladi:

python
ismlar = ["Ali", "Vali", "Guli"]
ballar = [85, 92, 78]

# enumerate(zip(...))
for i, (ism, ball) in enumerate(zip(ismlar, ballar), 1):
    print(f"{i}. {ism}: {ball}")

Ochish tuzilmasiga e'tibor bering:

python
for i, (ism, ball) in enumerate(zip(ismlar, ballar)):
#   ^  ^^^^^^^^^^^ — ichki juftlik qavs ichida

Teskari tartib — noto'g'ri:

python
for (i, ism), ball in zip(enumerate(ismlar), ballar):    # ⚠️ ishlaydi, lekin chalkash

Uch ro'yxat:

python
shaharlar = ["Toshkent", "Samarqand", "Buxoro"]

for i, (ism, ball, shahar) in enumerate(zip(ismlar, ballar, shaharlar), 1):
    print(f"{i}. {ism} ({shahar}): {ball}")

2.7. Ichma-ich enumerate

python
jadval = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

for i, qator in enumerate(jadval):
    for j, qiymat in enumerate(qator):
        print(f"[{i}][{j}] = {qiymat}")

Amaliy — matritsada qidirish:

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


print(topish(jadval, 5))            # (1, 1)

Diagonal:

python
for i, qator in enumerate(jadval):
    print(qator[i], end=" ")        # 1 5 9

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

2.8. enumerate alternativalari

1. itertools.count bilan zip:

python
from itertools import count

for i, x in zip(count(), royxat):   # enumerate bilan bir xil
    print(i, x)

for i, x in zip(count(1), royxat):  # start=1
    print(i, x)

enumerate — qisqaroq va tezroq.

2. Qo'lda hisoblagich:

python
i = 0
for x in royxat:                    # ❌ noidiomatik
    print(i, x)
    i += 1

3. range bilan zip:

python
for i, x in zip(range(len(royxat)), royxat):    # ❌ ortiqcha
    print(i, x)

4. Lug'at kaliti sifatida indeks:

python
lugat = dict(enumerate(royxat))
for i, x in lugat.items():          # ⚠️ ortiqcha qadam
    print(i, x)

Xulosa: enumerate — eng qisqa, eng tez va eng aniq usul.

2.9. Tuzoqlar

1. Bir martalik iterator:

python
e = enumerate(royxat)
birinchi = list(e)
ikkinchi = list(e)                  # ❌ bo'sh

2. Ochish tuzilmasi:

python
for i, x in enumerate(juftliklar):  # x — butun juftlik
    print(i, x)                     # 0 (1, 'a')

for i, (a, b) in enumerate(juftliklar):     # ✅ ichki ochish
    print(i, a, b)                          # 0 1 a

3. Elementni o'zgartirish:

python
for i, x in enumerate(royxat):
    x = x * 2                       # ❌ mahalliy nusxa

for i, x in enumerate(royxat):
    royxat[i] = x * 2               # ✅

4. start va indeks chalkashligi:

python
for i, x in enumerate(royxat, 1):
    print(royxat[i])                # ❌ i 1 dan boshlanadi!
    print(x)                        # ✅

start bilan i haqiqiy indeks emas.

5. Iteratsiya paytida o'zgartirish (6-dars):

python
for i, x in enumerate(royxat):
    if shart(x):
        del royxat[i]               # ❌ indekslar buziladi

6. Katta to'plamda list(enumerate(...)):

python
juftliklar = list(enumerate(katta_royxat))      # ⚠️ xotira 2x
for i, x in enumerate(katta_royxat):            # ✅ dangasa
    ...

3. Tez ma'lumotnoma

Asosiy

python
for i, x in enumerate(iterable):            0 dan
for i, x in enumerate(iterable, start=1):   1 dan
for i, x in enumerate(iterable, 100):       pozitsion

Xususiyatlari

text
Iterator      — bir martalik
len() shart emas — generator, fayl bilan ishlaydi
Dangasa       — cheksiz ketma-ketlik bilan ham
Tezroq        — range(len()) dan

Naqshlar

python
dict(enumerate(x))                  {0: 'a', 1: 'b'}
dict(enumerate(x, 1))               {1: 'a', 2: 'b'}
{v: i for i, v in enumerate(x)}     element → indeks
[i for i, v in enumerate(x) if c]   mos indekslar
next((i for i, v in enumerate(x) if c), -1)   birinchi indeks

zip bilan

python
for i, (a, b) in enumerate(zip(x, y), 1):
#   ^  ^^^^^^ — ichki ochish qavs ichida

Tuzoqlar

python
for i, x in enumerate(x, 1):
    x[i]                    ❌ i haqiqiy indeks emas

for i, x in enumerate(x):
    x = x * 2               ❌ mahalliy nusxa
    x[i] = x * 2            ✅

e = enumerate(x)
list(e); list(e)            ❌ ikkinchisi bo'sh

Qachon range(len())

python
for i in range(len(x)):
    x[i] *= 2               ✅ elementni o'zgartirish

for i in range(len(x) - 1):
    x[i], x[i+1]            ✅ qo'shni elementlar

4. Batafsil misollar

Misol 1 — enumerate asoslari

python
"""enumerate — barcha imkoniyat."""

import time
from itertools import count, islice

print("=== 1. Asosiy foydalanish ===")

mevalar = ["olma", "anor", "uzum", "shaftoli"]

print("  enumerate(mevalar):")
for i, meva in enumerate(mevalar):
    print(f"    {i}: {meva}")

print("\n  enumerate(mevalar, 1):")
for i, meva in enumerate(mevalar, 1):
    print(f"    {i}. {meva}")

print("\n  enumerate(mevalar, 100):")
for i, meva in enumerate(mevalar, 100):
    print(f"    #{i} {meva}")


print("\n\n=== 2. Nima qaytaradi ===")

e = enumerate("abc")
print(f"  type: {type(e)}")
print(f"  list: {list(enumerate('abc'))}")
print(f"  tuple: {tuple(enumerate('abc'))}")
print(f"  dict: {dict(enumerate('abc'))}")
print(f"  dict (1 dan): {dict(enumerate('abc', 1))}")


print("\n\n=== 3. ⚠️ Bir martalik iterator ===")

e = enumerate("abc")
print(f"  1-marta: {list(e)}")
print(f"  2-marta: {list(e)}  ← bo'sh!")

print("\n  next() bilan:")
e = enumerate("abc")
for _ in range(4):
    try:
        print(f"    {next(e)}")
    except StopIteration:
        print("    StopIteration ✅")


print("\n\n=== 4. len() shart emas ===")

print("  ✅ Generator bilan:")
gen = (x * 2 for x in range(3))
for i, x in enumerate(gen):
    print(f"    {i}: {x}")

print("\n  ✅ Cheksiz ketma-ketlik bilan:")
for i, x in enumerate(count(100, 5)):
    if i >= 3:
        break
    print(f"    {i}: {x}")

print("\n  ❌ range(len()) generator bilan ishlamaydi:")
gen = (x for x in range(3))
try:
    len(gen)
except TypeError as x:
    print(f"    len(generator) → TypeError: {x}")


print("\n\n=== 5. Sof Python ekvivalenti ===")


def mening_enumerate(iterable, start=0):
    n = start
    for element in iterable:
        yield n, element
        n += 1


print(f"  mening_enumerate('abc'):    {list(mening_enumerate('abc'))}")
print(f"  mening_enumerate('abc', 1): {list(mening_enumerate('abc', 1))}")
print(f"  enumerate('abc'):           {list(enumerate('abc'))}")


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

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

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

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

# faqat element
boshlandi = time.perf_counter()
jami3 = 0
for x in royxat:
    jami3 += x
vaqt_oddiy = time.perf_counter() - boshlandi

# qo'lda hisoblagich
boshlandi = time.perf_counter()
jami4 = 0
i = 0
for x in royxat:
    jami4 += x
    i += 1
vaqt_qolda = time.perf_counter() - boshlandi

assert jami1 == jami2 == jami3 == jami4

natijalar = [
    ("for x in royxat", vaqt_oddiy),
    ("enumerate(royxat)", vaqt_enum),
    ("qo'lda hisoblagich", vaqt_qolda),
    ("range(len(royxat))", vaqt_range),
]

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

Natijaning muhim qismi:

text
=== 2. Nima qaytaradi ===
  type: <class 'enumerate'>
  list: [(0, 'a'), (1, 'b'), (2, 'c')]
  dict: {0: 'a', 1: 'b', 2: 'c'}
  dict (1 dan): {1: 'a', 2: 'b', 3: 'c'}

=== 4. len() shart emas ===
  ✅ Cheksiz ketma-ketlik bilan:
    0: 100
    1: 105
    2: 110

  ❌ range(len()) generator bilan ishlamaydi:
    len(generator) → TypeError: object of type 'generator' has no len()

=== 6. Tezlik ===
  Usul                        Vaqt   Nisbat
  ──────────────────────────────────────────
  for x in royxat            11.8 ms    1.00x
  enumerate(royxat)          14.2 ms    1.20x
  qo'lda hisoblagich         17.4 ms    1.47x
  range(len(royxat))         19.1 ms    1.62x

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

Misol 2 — Amaliy naqshlar

python
"""enumerate bilan tipik masalalar."""

from dataclasses import dataclass

print("=== 1. Raqamlangan ro'yxat ===")

MENYU = ["Ma'lumot ko'rish", "Qo'shish", "Tahrirlash", "O'chirish", "Chiqish"]

print("  ┌─ MENYU")
for i, punkt in enumerate(MENYU, 1):
    print(f"  │  {i}. {punkt}")
print("  └─")


print("\n\n=== 2. Fayl qatorlari ===")

MATN = """def salom():
    print("Salom")

def xayr()
    print("Xayr")
"""

print("  Sintaksis tekshiruvi:")
for raqam, qator in enumerate(MATN.splitlines(), 1):
    xato = ""
    if qator.strip().startswith("def") and not qator.rstrip().endswith(":"):
        xato = "  ← ⚠️ ikki nuqta yo'q"
    print(f"    {raqam:>3} | {qator}{xato}")


print("\n\n=== 3. Indeks topish ===")

royxat = ["a", "b", "c", "b", "d"]
qidiruv = "b"

print(f"  Ro'yxat: {royxat}, qidiruv: {qidiruv!r}\n")

# Birinchi indeks
birinchi = next((i for i, x in enumerate(royxat) if x == qidiruv), -1)
print(f"  Birinchi indeks:  {birinchi}")
print(f"  .index() bilan:   {royxat.index(qidiruv)}")

# Barcha indekslar
barchasi = [i for i, x in enumerate(royxat) if x == qidiruv]
print(f"  Barcha indekslar: {barchasi}")

# Oxirgi indeks
oxirgi = max((i for i, x in enumerate(royxat) if x == qidiruv), default=-1)
print(f"  Oxirgi indeks:    {oxirgi}")

# Topilmaganda
yoq = next((i for i, x in enumerate(royxat) if x == "z"), -1)
print(f"  Yo'q element:     {yoq}")


print("\n\n=== 4. Lug'atlar ===")

mevalar = ["olma", "anor", "uzum"]

print(f"  Indeks → element: {dict(enumerate(mevalar))}")
print(f"  1 dan:            {dict(enumerate(mevalar, 1))}")
print(f"  Element → indeks: {dict((v, i) for i, v in enumerate(mevalar))}")
print(f"  Generator bilan:  {{v: i for i, v in enumerate(mevalar)}}")


print("\n\n=== 5. zip bilan ===")

ismlar = ["Ali", "Vali", "Guli"]
ballar = [85, 92, 78]
shaharlar = ["Toshkent", "Samarqand", "Buxoro"]

print("  Ikki ro'yxat:")
for i, (ism, ball) in enumerate(zip(ismlar, ballar), 1):
    print(f"    {i}. {ism:<6} {ball}")

print("\n  Uch ro'yxat:")
for i, (ism, ball, shahar) in enumerate(zip(ismlar, ballar, shaharlar), 1):
    print(f"    {i}. {ism:<6} {ball:>3}  {shahar}")


print("\n\n=== 6. Birinchi/oxirgi elementni ajratish ===")

elementlar = ["birinchi", "ikkinchi", "uchinchi", "oxirgi"]
n = len(elementlar)

print("  Daraxt ko'rinishida:")
for i, x in enumerate(elementlar):
    if i == n - 1:
        print(f"    └── {x}")
    else:
        print(f"    ├── {x}")


print("\n\n=== 7. Har n-elementni ===")

sonlar = list(range(20))

print(f"  Manba: {sonlar}\n")
print(f"  Har 3-element (enumerate): "
      f"{[x for i, x in enumerate(sonlar) if i % 3 == 0]}")
print(f"  Har 3-element (kesim):     {sonlar[::3]}")
print(f"  ← kesim tezroq (4.2-dars)")


print("\n\n=== 8. Amaliy: jadval ===")


@dataclass
class Talaba:
    ism: str
    ball: int
    kurs: int


TALABALAR = [
    Talaba("Sarvarbek Karimov", 88, 2),
    Talaba("Aziza Rahimova", 95, 3),
    Talaba("Bekzod Toshmatov", 72, 1),
    Talaba("Dilnoza Yusupova", 91, 2),
]

# Ball bo'yicha saralash
saralangan = sorted(TALABALAR, key=lambda t: -t.ball)

print(f"  {'#':>3} {'Talaba':<20} {'Kurs':>5} {'Ball':>6} {'Reyting'}")
print("  " + "─" * 52)

for orin, t in enumerate(saralangan, 1):
    if orin == 1:
        belgi = "🥇"
    elif orin == 2:
        belgi = "🥈"
    elif orin == 3:
        belgi = "🥉"
    else:
        belgi = "  "
    print(f"  {orin:>3} {t.ism:<20} {t.kurs:>5} {t.ball:>6} {belgi}")

ortacha = sum(t.ball for t in TALABALAR) / len(TALABALAR)
print("  " + "─" * 52)
print(f"  {'':>3} {'OʻRTACHA':<20} {'':>5} {ortacha:>6.1f}")

Natijaning muhim qismi:

text
=== 3. Indeks topish ===
  Ro'yxat: ['a', 'b', 'c', 'b', 'd'], qidiruv: 'b'

  Birinchi indeks:  1
  .index() bilan:   1
  Barcha indekslar: [1, 3]
  Oxirgi indeks:    3
  Yo'q element:     -1

=== 6. Birinchi/oxirgi elementni ajratish ===
  Daraxt ko'rinishida:
    ├── birinchi
    ├── ikkinchi
    ├── uchinchi
    └── oxirgi

=== 8. Amaliy: jadval ===
    # Talaba                Kurs   Ball Reyting
  ────────────────────────────────────────────────────
    1 Aziza Rahimova           3     95 🥇
    2 Dilnoza Yusupova         2     91 🥈
    3 Sarvarbek Karimov        2     88 🥉
    4 Bekzod Toshmatov         1     72   

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

Misol 3 — Tuzoqlar

python
"""enumerate bilan bog'liq xatolar."""

print("=== 1. ⚠️ Ochish tuzilmasi ===")

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

print("  ❌ Ichki ochishsiz:")
for i, x in enumerate(juftliklar):
    print(f"    i={i}, x={x}")

print("\n  ✅ Ichki ochish bilan:")
for i, (harf, son) in enumerate(juftliklar):
    print(f"    i={i}, harf={harf}, son={son}")


print("\n\n=== 2. ⚠️ start va haqiqiy indeks ===")

royxat = ["a", "b", "c"]

print("  ❌ start=1 bilan indeks sifatida ishlatish:")
for i, x in enumerate(royxat, 1):
    try:
        print(f"    i={i}, x={x!r}, royxat[i]={royxat[i]!r}")
    except IndexError:
        print(f"    i={i}, x={x!r}, royxat[i] → ❌ IndexError")

print("\n  ✅ To'g'ri:")
for i, x in enumerate(royxat, 1):
    print(f"    Raqam={i}, element={x!r}, haqiqiy indeks={i - 1}")


print("\n\n=== 3. ⚠️ Elementni o'zgartirish ===")

sonlar = [1, 2, 3, 4]
print(f"  Asl: {sonlar}")

# ❌ Mahalliy nusxa
sinov = sonlar[:]
for i, x in enumerate(sinov):
    x = x * 2
print(f"  ❌ x = x * 2:          {sinov}  ← o'zgarmadi")

# ✅ Indeks orqali
sinov = sonlar[:]
for i, x in enumerate(sinov):
    sinov[i] = x * 2
print(f"  ✅ sinov[i] = x * 2:   {sinov}")

# ✅ range bilan (oddiyroq)
sinov = sonlar[:]
for i in range(len(sinov)):
    sinov[i] *= 2
print(f"  ✅ range + sinov[i]:   {sinov}")

# ✅ Generator (eng idiomatik)
sinov = [x * 2 for x in sonlar]
print(f"  ✅ Generator:          {sinov}")


print("\n\n=== 4. ⚠️ Iteratsiya paytida o'chirish ===")

sonlar = [1, 2, 3, 4, 5, 6]
print(f"  Asl: {sonlar}")
print("  Maqsad: juft sonlarni o'chirish\n")

# ❌ enumerate bilan o'chirish
sinov = sonlar[:]
for i, x in enumerate(sinov):
    if i < len(sinov) and sinov[i] % 2 == 0:
        del sinov[i]
print(f"  ❌ enumerate + del:  {sinov}")

# ✅ Teskari yo'nalish
sinov = sonlar[:]
for i in range(len(sinov) - 1, -1, -1):
    if sinov[i] % 2 == 0:
        del sinov[i]
print(f"  ✅ Teskari + del:    {sinov}")

# ✅ Generator
sinov = [x for x in sonlar if x % 2 != 0]
print(f"  ✅ Generator:        {sinov}")


print("\n\n=== 5. ⚠️ Bir martalik ===")

e = enumerate("abc")
birinchi = list(e)
ikkinchi = list(e)
print(f"  1-marta: {birinchi}")
print(f"  2-marta: {ikkinchi}  ← bo'sh")

print("\n  ✅ Qayta kerak bo'lsa:")
juftliklar = list(enumerate("abc"))
print(f"    Saqlangan: {juftliklar}")
print(f"    1-marta:   {[x for x in juftliklar]}")
print(f"    2-marta:   {[x for x in juftliklar]}  ✅")


print("\n\n=== 6. ⚠️ Xotira ===")

import sys

katta = list(range(100_000))

e = enumerate(katta)
juftliklar = list(enumerate(katta))

print(f"  Asl ro'yxat:           {sys.getsizeof(katta):>12,} bayt")
print(f"  enumerate obyekti:     {sys.getsizeof(e):>12,} bayt")
print(f"  list(enumerate(...)):  {sys.getsizeof(juftliklar):>12,} bayt")
print("\n  ⚠️ list(enumerate()) — xotira ~2x oshadi (juftliklar)")
print("  ✅ To'g'ridan-to'g'ri sikl — dangasa")


print("\n\n=== 7. Qachon range(len()) to'g'ri ===")

print("""
  ✅ Elementni o'zgartirish:
       for i in range(len(x)):
           x[i] *= 2

  ✅ Qo'shni elementlar:
       for i in range(len(x) - 1):
           print(x[i], x[i + 1])

  ✅ Faqat indeks kerak:
       for i in range(len(x)):
           print(i)

  ✅ Teskari (o'chirish uchun):
       for i in range(len(x) - 1, -1, -1):
           del x[i]

  ❌ Qolgan hamma holatda — enumerate
""")

Natijaning muhim qismi:

text
=== 2. ⚠️ start va haqiqiy indeks ===
  ❌ start=1 bilan indeks sifatida ishlatish:
    i=1, x='a', royxat[i]='b'
    i=2, x='b', royxat[i]='c'
    i=3, x='c', royxat[i] → ❌ IndexError

=== 3. ⚠️ Elementni o'zgartirish ===
  Asl: [1, 2, 3, 4]
  ❌ x = x * 2:          [1, 2, 3, 4]  ← o'zgarmadi
  ✅ sinov[i] = x * 2:   [2, 4, 6, 8]
  ✅ range + sinov[i]:   [2, 4, 6, 8]
  ✅ Generator:          [2, 4, 6, 8]

=== 6. ⚠️ Xotira ===
  Asl ro'yxat:                800,056 bayt
  enumerate obyekti:               72 bayt
  list(enumerate(...)):       800,984 bayt

Nima ko'rsatdi: 2.9-bo'lim.

Misol 4 — Amaliy: matn tahlilchisi

python
"""enumerate bilan to'liq matn tahlili."""

import re
from collections import Counter
from dataclasses import dataclass

MATN = """Python — bu yuqori darajali dasturlash tili.
U 1991-yilda Guido van Rossum tomonidan yaratilgan.

Python soddaligi bilan mashhur.
Bugungi kunda u eng ko'p ishlatiladigan tillardan biri.
Python veb, ma'lumot tahlili va sun'iy intellektda qo'llaniladi."""


@dataclass
class Xato:
    qator: int
    ustun: int
    xabar: str


print("=== 1. Qatorlarni raqamlash ===")

for raqam, qator in enumerate(MATN.splitlines(), 1):
    belgi = " " if qator.strip() else "·"
    print(f"  {raqam:>3} │{belgi}{qator}")


print("\n\n=== 2. So'z statistikasi ===")

sozlar = MATN.lower().split()
toza_sozlar = [s.strip(".,!?;:—") for s in sozlar]

print(f"  Jami so'zlar:   {len(toza_sozlar)}")
print(f"  Noyob so'zlar:  {len(set(toza_sozlar))}")

hisob = Counter(toza_sozlar)
print(f"\n  Eng ko'p uchraydigan 5 ta:")
for orin, (soz, soni) in enumerate(hisob.most_common(5), 1):
    chiziq = "█" * soni
    print(f"    {orin}. {soz:<16} {soni:>2}  {chiziq}")


print("\n\n=== 3. Uzun qatorlarni topish ===")

MAX_UZUNLIK = 60

uzun_qatorlar = [
    (raqam, len(qator), qator)
    for raqam, qator in enumerate(MATN.splitlines(), 1)
    if len(qator) > MAX_UZUNLIK
]

if uzun_qatorlar:
    print(f"  {MAX_UZUNLIK} belgidan uzun qatorlar:")
    for raqam, uzunlik, qator in uzun_qatorlar:
        print(f"    {raqam}-qator ({uzunlik} belgi): {qator[:40]}...")
else:
    print(f"  ✅ Barcha qator {MAX_UZUNLIK} belgidan qisqa")


print("\n\n=== 4. Kalit so'z qidirish (pozitsiya bilan) ===")

KALIT_SOZLAR = ["Python", "dasturlash", "ma'lumot"]

for kalit in KALIT_SOZLAR:
    topilgan = []
    for raqam, qator in enumerate(MATN.splitlines(), 1):
        for moslik in re.finditer(re.escape(kalit), qator, re.IGNORECASE):
            topilgan.append((raqam, moslik.start() + 1))

    print(f"\n  {kalit!r}: {len(topilgan)} marta")
    for qator, ustun in topilgan:
        print(f"    {qator}-qator, {ustun}-ustun")


print("\n\n=== 5. Sintaksis tekshiruvi (soxta) ===")

KOD = """def salom(ism):
    print(f"Salom, {ism}")

def xayr(ism)
    print("Xayr")

class Odam
    def __init__(self):
        pass
"""

xatolar: list[Xato] = []

for raqam, qator in enumerate(KOD.splitlines(), 1):
    tozalangan = qator.strip()

    # def yoki class ikki nuqta bilan tugashi kerak
    if (tozalangan.startswith(("def ", "class "))
            and not tozalangan.endswith(":")):
        ustun = len(qator.rstrip()) + 1
        xatolar.append(Xato(raqam, ustun, "':' yetishmaydi"))

    # Tab tekshiruvi
    if "\t" in qator:
        ustun = qator.index("\t") + 1
        xatolar.append(Xato(raqam, ustun, "Tab ishlatilgan (bo'sh joy kerak)"))

print("  Kod:")
for raqam, qator in enumerate(KOD.splitlines(), 1):
    qator_xatolari = [x for x in xatolar if x.qator == raqam]
    belgi = "❌" if qator_xatolari else "  "
    print(f"  {belgi} {raqam:>3} │ {qator}")

if xatolar:
    print(f"\n  {len(xatolar)} ta xato topildi:")
    for x in xatolar:
        print(f"    {x.qator}:{x.ustun} — {x.xabar}")


print("\n\n=== 6. Diff (farqlarni ko'rsatish) ===")

ESKI = ["birinchi", "ikkinchi", "uchinchi", "to'rtinchi"]
YANGI = ["birinchi", "IKKINCHI", "uchinchi", "beshinchi", "oltinchi"]

print(f"  {'#':>3} {'Eski':<14} {'Yangi':<14} {'Holat'}")
print("  " + "─" * 46)

max_uzunlik = max(len(ESKI), len(YANGI))

for i in range(max_uzunlik):
    eski = ESKI[i] if i < len(ESKI) else ""
    yangi = YANGI[i] if i < len(YANGI) else ""

    if eski == yangi:
        holat = "   "
    elif not eski:
        holat = "+ qo'shildi"
    elif not yangi:
        holat = "- o'chirildi"
    else:
        holat = "~ o'zgardi"

    print(f"  {i + 1:>3} {eski:<14} {yangi:<14} {holat}")

Natijaning muhim qismi:

text
=== 3. Uzun qatorlarni topish ===
  60 belgidan uzun qatorlar:
    6-qator (64 belgi): Python veb, ma'lumot tahlili va sun'iy i...

=== 5. Sintaksis tekshiruvi (soxta) ===
  Kod:
       1 │ def salom(ism):
       2 │     print(f"Salom, {ism}")
       3 │ 
    ❌   4 │ def xayr(ism)
       5 │     print("Xayr")
       6 │ 
    ❌   7 │ class Odam
       8 │     def __init__(self):
       9 │         pass

  2 ta xato topildi:
    4:14 — ':' yetishmaydi
    7:11 — ':' yetishmaydi

=== 6. Diff (farqlarni ko'rsatish) ===
    # Eski           Yangi          Holat
  ──────────────────────────────────────────────
    1 birinchi       birinchi          
    2 ikkinchi       IKKINCHI       ~ o'zgardi
    3 uchinchi       uchinchi          
    4 to'rtinchi     beshinchi      ~ o'zgardi
    5                oltinchi       + qo'shildi

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


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

Noto'g'ri fikr To'g'risi
"enumerate ro'yxat qaytaradi" Iterator — bir martalik
"range(len(x)) va enumerate bir xil" enumerate len() talab qilmaydi va tezroq
"start — qadam" Boshlang'ich qiymat. Qadam doim 1
"start=1 bilan i — indeks" Yo'q — haqiqiy indeks i - 1
"for i, x in ...: x = 2 elementni o'zgartiradi" Mahalliy nusxa. royxat[i] = 2 kerak
"enumerate faqat ro'yxat bilan" Har qanday iterable — generator, fayl, cheksiz
"list(enumerate(x)) bepul" Xotira ~2x oshadi (juftliklar)
"range(len()) hech qachon kerak emas" Elementni o'zgartirishda va qo'shni elementlarda

6. Keng tarqalgan xatolar va yechimlari

1. range(len()) noidiomatik ishlatish

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

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

2. start bilan indeks chalkashligi

python
for i, x in enumerate(royxat, 1):
    print(royxat[i])                # ❌ IndexError
    print(x)                        # ✅

3. Elementni o'zgartirish

python
for i, x in enumerate(royxat):
    x *= 2                          # ❌ mahalliy
    royxat[i] = x * 2               # ✅

4. Ichki ochishni unutish

python
for i, x in enumerate(juftliklar):
    print(x[0], x[1])               # ⚠️ noqulay

for i, (a, b) in enumerate(juftliklar):     # ✅
    print(a, b)

5. Bir martalik iteratorni qayta ishlatish

python
e = enumerate(x)
list(e); list(e)                    # ❌ ikkinchisi bo'sh
juftliklar = list(enumerate(x))     # ✅ saqlang

6. Iteratsiya paytida o'chirish

python
for i, x in enumerate(royxat):
    if shart(x):
        del royxat[i]               # ❌

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

7. Katta to'plamda list(enumerate())

python
juftliklar = list(enumerate(katta))     # ⚠️ xotira
for i, x in enumerate(katta):           # ✅ dangasa
    ...

8. zip bilan noto'g'ri ochish

python
for i, ism, ball in enumerate(zip(ismlar, ballar)):     # ❌ ValueError
for i, (ism, ball) in enumerate(zip(ismlar, ballar)):   # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 5.6-dars (o'tilgan): for sikli, ochish
  • 5.7-dars (o'tilgan): range — qachon kerak
  • 5.9-dars: zip — enumerate bilan birga
  • 5.11-dars: ichma-ich sikllar
  • 6-qism: ro'yxat/lug'at generatorlari
  • 10, 15-qismlar: generatorlar, itertools
  • 16-qism: fayl qatorlarini raqamlash
  • Kundalik kodda: eng ko'p ishlatiladigan ichki funksiyalardan biri

8. Eng yaxshi amaliyotlar

  1. range(len(x)) o'rniga enumerate(x). Tezroq, xavfsizroq, universalroq.

  2. Foydalanuvchiga ko'rsatishda start=1. Odamlar 1 dan sanaydi.

  3. Indeks kerak bo'lmasa enumerate ishlatmang. for x in royxat: — eng tez.

  4. Ichki ochishni ishlating. for i, (a, b) in enumerate(zip(...)).

  5. Elementni o'zgartirishda royxat[i] = .... Sikl o'zgaruvchisi — nusxa.

  6. start bilan i haqiqiy indeks emasligini eslang.

  7. Katta to'plamda list(enumerate()) qilmang. Dangasa sikl ishlating.

  8. Indeks topish uchun generator ishlating. next((i for i, x in enumerate(y) if c), -1).


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
1.  list(enumerate("ab"))
2.  list(enumerate("ab", 1))
3.  dict(enumerate("ab"))
4.  e = enumerate("ab"); list(e); list(e)
5.  [i for i, x in enumerate("abc")]
6.  [x for i, x in enumerate("abc")]
7.  [(i, x) for i, x in enumerate("abc") if i % 2 == 0]
8.  {v: i for i, v in enumerate("abc")}
Javoblar
  1. [(0, 'a'), (1, 'b')]
  2. [(1, 'a'), (2, 'b')]
  3. {0: 'a', 1: 'b'}
  4. Birinchisi [(0,'a'),(1,'b')], ikkinchisi []
  5. [0, 1, 2]
  6. ['a', 'b', 'c']
  7. [(0, 'a'), (2, 'c')]
  8. {'a': 0, 'b': 1, 'c': 2}

Vazifa 2: enumerate ga o'tkazing

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

2.  i = 0
    for x in royxat:
        print(i, x)
        i += 1

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

4.  indeks = 1
    for qator in fayl:
        print(indeks, qator)
        indeks += 1
Javoblar
python
1.  for i, x in enumerate(royxat): print(i, x)
2.  for i, x in enumerate(royxat): print(i, x)
3.  for i, (x, y) in enumerate(zip(a, b)): print(i, x, y)
4.  for i, qator in enumerate(fayl, 1): print(i, qator)

Vazifa 3: Indeks topish

royxat = ["a", "b", "c", "b", "a", "b"] uchun yozing:

  1. Birinchi "b" indeksi
  2. Oxirgi "b" indeksi
  3. Barcha "b" indekslari
  4. Har bir element uchun barcha indekslar (lug'at)
  5. Takrorlanuvchi elementlar va ularning indekslari
Javoblar
python
royxat = ["a", "b", "c", "b", "a", "b"]

# 1
next((i for i, x in enumerate(royxat) if x == "b"), -1)     # 1

# 2
max((i for i, x in enumerate(royxat) if x == "b"), default=-1)   # 5

# 3
[i for i, x in enumerate(royxat) if x == "b"]               # [1, 3, 5]

# 4
from collections import defaultdict
indekslar = defaultdict(list)
for i, x in enumerate(royxat):
    indekslar[x].append(i)
# {'a': [0, 4], 'b': [1, 3, 5], 'c': [2]}

# 5
takrorlar = {k: v for k, v in indekslar.items() if len(v) > 1}

Vazifa 4: Matn tahlilchisi

4-misoldagi dasturni kengaytiring:

  1. Har qator uchun so'zlar sonini ko'rsating
  2. Eng uzun/qisqa qatorni toping
  3. Bo'sh qatorlarni raqamlang
  4. Har bir kalit so'z uchun kontekst (oldingi/keyingi 20 belgi)

Vazifa 5: Progressiv raqamlash

Ichma-ich ro'yxatni raqamlang:

python
malumot = {
    "Bo'lim A": ["punkt 1", "punkt 2"],
    "Bo'lim B": ["punkt 3", "punkt 4", "punkt 5"],
}
text
1. Bo'lim A
   1.1. punkt 1
   1.2. punkt 2
2. Bo'lim B
   2.1. punkt 3
   2.2. punkt 4
   2.3. punkt 5

Vazifa 6: Diff algoritmi

4-misoldagi diff ni yaxshilang:

  1. Qo'shilgan/o'chirilgan qatorlarni to'g'ri aniqlang (siljish bilan)
  2. difflib moduli bilan solishtiring
  3. Rangli chiqish (ANSI kodlari bilan)

Vazifa 7: O'ylash

Nega enumerate range(len()) dan tezroq?

Javob

Uch sabab:

1. Indeksga murojaat yo'q.

python
for i in range(len(x)):
    y = x[i]                # ← BINARY_SUBSCR bytecode buyrug'i

x[i] — bu x.__getitem__(i) chaqiruvi. Har iteratsiyada:

  • Indeks chegarasi tekshiriladi
  • Xotiradan element olinadi

enumerate esa elementni iteratordan to'g'ridan-to'g'ri oladi.

2. enumerate C darajasida.

enumerate — CPython'da C tilida yozilgan. U ichki hisoblagichni saqlaydi va juftlikni bir amalda yaratadi.

range(len(x)) esa:

  • len(x) chaqiruvi
  • range obyekti yaratish
  • Har iteratsiyada range dan son olish
  • Keyin x[i]

3. Bytecode qisqaroq:

text
range(len(x)):          enumerate(x):
  LOAD_GLOBAL len         LOAD_GLOBAL enumerate
  LOAD_FAST x             LOAD_FAST x
  CALL                    CALL
  LOAD_GLOBAL range       GET_ITER
  CALL                    FOR_ITER
  GET_ITER                UNPACK_SEQUENCE
  FOR_ITER                STORE_FAST i
  STORE_FAST i            STORE_FAST x
  LOAD_FAST x             ...
  LOAD_FAST i
  BINARY_SUBSCR           ← qo'shimcha
  ...

Amalda farq ~20-40%. Katta emas, lekin enumerate baribir o'qish oson va xavfsizroq (off-by-one xatolari yo'q).

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


Xulosa

Bu darsda enumerate() ni o'rgandik.

Eng muhim uch fikr:

  1. range(len(x)) o'rniga enumerate(x). U tezroq, len() talab qilmaydi va generator, fayl, hatto cheksiz ketma-ketlik bilan ham ishlaydi.

  2. start — boshlang'ich qiymat, indeks emas. enumerate(x, 1) bilan i haqiqiy indeks emas — x[i] xato beradi.

  3. Sikl o'zgaruvchisi — nusxa. for i, x in enumerate(royxat): x *= 2 ro'yxatni o'zgartirmaydi. royxat[i] = x * 2 kerak — yoki eng yaxshisi, ro'yxat generatori.

Keyingi darsda zip() ni o'rganamiz — bir necha to'plamni parallel bo'ylab yurish va Pythonning eng chiroyli funksiyalaridan biri.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.8-dars: enumerate() — IlmHamroh