IlmHamroh
Python kursi/Malumot tuzilmalari16/18-dars34 daqiqa
Mundarija (21)

6.16-dars: dict va set generatorlari

6-QISM — MA'LUMOT TUZILMALARI · 16-dars


1. Kirish va motivatsiya

Ro'yxat generatori sintaksisi set va dict uchun ham ishlaydi:

python
[x ** 2 for x in range(5)]              # list
{x ** 2 for x in range(5)}              # set
{x: x ** 2 for x in range(5)}           # dict

Uchtasi bir xil ko'rinadi, lekin xatti-harakati farqli:

python
MALUMOT = ["olma", "anor", "olma", "behi"]

[s.upper() for s in MALUMOT]            # ['OLMA','ANOR','OLMA','BEHI']  4 element
{s.upper() for s in MALUMOT}            # {'OLMA','ANOR','BEHI'}         3 element ← takror yo'q
{s: len(s) for s in MALUMOT}            # {'olma':4,'anor':4,'behi':4}   3 kalit

Va tuzoqlar bor:

python
{}                                      # ⚠️ bo'sh LUG'AT
{x for x in []}                         # ✅ bo'sh to'plam

{x: y for x, y in [("a",1), ("a",2)]}   # {'a': 2}  ← qaysi qoladi?

{[1,2]: "x" for _ in range(1)}          # ❌ unhashable

Bu darsda:

  • set generatori — noyoblik va tartibsizlik
  • dict generatori — kalit to'qnashuvi
  • Lug'atni invertlash, filtrlash, o'zgartirish
  • zip, enumerate, items() bilan naqshlar
  • Ichma-ich lug'at generatorlari
  • Counter, defaultdict bilan solishtirish

2. Nazariya — chuqur tushuntirish

2.1. set generatori

python
{IFODA for X in KETMA-KETLIK}
{IFODA for X in KETMA-KETLIK if SHART}
python
{x ** 2 for x in range(5)}              # {0, 1, 4, 9, 16}
{s.lower() for s in sozlar}             # noyob, kichik harfda
{len(s) for s in sozlar}                # noyob uzunliklar
{x for x in r if shart(x)}

Ikki xususiyat:

1. Takrorlar avtomatik yo'qoladi:

python
{x % 3 for x in range(10)}              # {0, 1, 2}  — 10 element → 3

2. Elementlar hashlanishi kerak:

python
{[x] for x in range(3)}                 # ❌ unhashable type: 'list'
{(x,) for x in range(3)}                # ✅
{frozenset([x]) for x in range(3)}      # ✅

Bo'sh to'plam generatori yo'q:

python
{}                                      # dict!
{x for x in []}                         # ✅ bo'sh to'plam
set()                                   # ✅

Amaliy naqshlar:

python
# Noyob qiymatlar
noyob_shaharlar = {x["shahar"] for x in yozuvlar}

# Noyob kalitlar
barcha_kalitlar = {k for d in lugatlar for k in d}

# Tez tekshirish uchun to'plam
RUXSAT = {x.lower() for x in ruxsat_royxati}
if kengaytma in RUXSAT: ...

# Farqni topish
yangi = {x.id for x in yangi_yozuvlar} - {x.id for x in eski_yozuvlar}

Tartib yo'q:

python
{x for x in [3, 1, 2]}                  # tartib aniqlanmagan
sorted({x for x in [3, 1, 2]})          # [1, 2, 3] ✅

Tartib va noyoblik ikkalasi kerak bo'lsa:

python
list(dict.fromkeys(r))                  # ⭐ tartib saqlanadi

2.2. dict generatori

python
{KALIT: QIYMAT for X in KETMA-KETLIK}
{KALIT: QIYMAT for X in KETMA-KETLIK if SHART}
python
{x: x ** 2 for x in range(5)}           # {0:0, 1:1, 2:4, 3:9, 4:16}
{s: len(s) for s in sozlar}
{k: v for k, v in juftliklar}
{k: v for k, v in d.items() if shart(v)}

Kalit to'qnashuvi — OXIRGISI g'olib:

python
{k: v for k, v in [("a", 1), ("b", 2), ("a", 3)]}
# {'a': 3, 'b': 2}  ← 'a' uchun 3 qoldi

Bu — oddiy lug'at qoidasi (6.10-dars).

Birinchisini saqlash kerak bo'lsa:

python
natija = {}
for k, v in juftliklar:
    natija.setdefault(k, v)             # ✅ birinchisi

# yoki teskari tartibda
{k: v for k, v in reversed(juftliklar)}

Kalit hashlanishi kerak:

python
{[x]: x for x in range(3)}              # ❌ unhashable
{(x,): x for x in range(3)}             # ✅

1, 1.0, True — bir kalit:

python
{x: str(x) for x in [1, 1.0, True]}     # {1: 'True'}

2.3. Keng tarqalgan naqshlar

1. Invertlash (kalit ↔ qiymat):

python
teskari = {v: k for k, v in d.items()}

Qiymatlar noyob bo'lmasa — yo'qotish:

python
d = {"a": 1, "b": 2, "c": 1}
{v: k for k, v in d.items()}            # {1: 'c', 2: 'b'}  ← 'a' yo'qoldi

Barcha kalitlarni saqlash:

python
from collections import defaultdict
teskari = defaultdict(list)
for k, v in d.items():
    teskari[v].append(k)
# {1: ['a', 'c'], 2: ['b']}

Qiymatlar hashlanishi kerak:

python
d = {"a": [1, 2]}
{v: k for k, v in d.items()}            # ❌ unhashable
{tuple(v): k for k, v in d.items()}     # ✅

2. Filtrlash:

python
{k: v for k, v in d.items() if v > 10}          # qiymat bo'yicha
{k: v for k, v in d.items() if k.startswith("a")}   # kalit bo'yicha
{k: d[k] for k in kerakli_kalitlar if k in d}   # kalitlar to'plami bo'yicha

3. Qiymatlarni o'zgartirish:

python
{k: v * 2 for k, v in d.items()}
{k: f(v) for k, v in d.items()}
{k: v.strip() if isinstance(v, str) else v for k, v in d.items()}

4. Kalitlarni o'zgartirish:

python
{k.lower(): v for k, v in d.items()}
{yangi_nomlar.get(k, k): v for k, v in d.items()}

Kalit o'zgartirishda to'qnashuv:

python
d = {"Ism": 1, "ISM": 2}
{k.lower(): v for k, v in d.items()}    # {'ism': 2}  ← birinchisi yo'qoldi

5. zip bilan:

python
{k: v for k, v in zip(kalitlar, qiymatlar)}
dict(zip(kalitlar, qiymatlar))          # ⭐ soddaroq

Generator kerak emas bo'lsa dict() ishlating:

python
{k: v for k, v in juftliklar}           # ⚠️ ortiqcha
dict(juftliklar)                        # ✅

6. enumerate bilan — indeks jadvali:

python
{s: i for i, s in enumerate(sozlar)}    # so'z → indeks
{i: s for i, s in enumerate(sozlar)}    # indeks → so'z

7. Guruhlash uchun to'plam:

python
{harf: {s for s in sozlar if s.startswith(harf)}
 for harf in {s[0] for s in sozlar}}

O(n²) — defaultdict yaxshiroq:

python
guruhlar = defaultdict(set)
for s in sozlar:
    guruhlar[s[0]].add(s)

8. Sanash:

python
{x: r.count(x) for x in set(r)}         # ❌ O(n²)
dict(Counter(r))                        # ✅ O(n)

2.4. Ichma-ich generatorlar

Lug'at ichida lug'at:

python
{i: {j: i * j for j in range(1, 4)} for i in range(1, 4)}
# {1: {1:1, 2:2, 3:3}, 2: {1:2, 2:4, 3:6}, 3: {1:3, 2:6, 3:9}}

Lug'at ichida ro'yxat:

python
{s: [c for c in s] for s in sozlar}
{k: [x for x in v if x > 0] for k, v in d.items()}

Ro'yxat ichida lug'at:

python
[{k: v} for k, v in d.items()]
[{**x, "yangi": 1} for x in yozuvlar]

Tekislash (ikki for):

python
{k: v for d in lugatlar for k, v in d.items()}       # birlashtirish

Bu {**d1, **d2, ...} bilan bir xil, lekin dinamik ro'yxat uchun qulay.

Ichma-ich lug'atdan barcha kalitlar:

python
{k for d in ichma_ich.values() for k in d}

2.5. Qachon generator, qachon boshqa

dict() konstruktori yetarli bo'lsa:

python
{k: v for k, v in juftliklar}           # ⚠️
dict(juftliklar)                        # ✅

{k: v for k, v in zip(a, b)}            # ⚠️
dict(zip(a, b))                         # ✅

{k: 0 for k in kalitlar}                # ⚠️
dict.fromkeys(kalitlar, 0)              # ✅ (o'zgarmas qiymat!)

set() yetarli bo'lsa:

python
{x for x in r}                          # ⚠️
set(r)                                  # ✅

{x for x in r if shart(x)}              # ✅ generator kerak
set(filter(shart, r))                   # ✅ ham

Counter yaxshiroq:

python
{x: r.count(x) for x in set(r)}         # ❌ O(n²)
Counter(r)                              # ✅ O(n)

defaultdict yaxshiroq:

python
{k: [x for x in r if kalit(x) == k] for k in {kalit(x) for x in r}}     # ❌ O(n²)

guruhlar = defaultdict(list)            # ✅ O(n)
for x in r:
    guruhlar[kalit(x)].append(x)

Umumiy qoida: generator bir marta o'tish uchun. Har element uchun butun ketma-ketlikni qayta ko'rish kerak bo'lsa — O(n²), boshqa yechim kerak.

2.6. Tezlik

python
import timeit

# dict yaratish
timeit.timeit("{k: v for k, v in juftliklar}", ...)     # ~1.3x
timeit.timeit("dict(juftliklar)", ...)                  # ~1.0x  ⭐

# set yaratish
timeit.timeit("{x for x in r}", ...)                    # ~1.2x
timeit.timeit("set(r)", ...)                            # ~1.0x  ⭐

# Filtrlash bilan
timeit.timeit("{x for x in r if x % 2}", ...)           # ~1.0x  ⭐
timeit.timeit("set(filter(lambda x: x % 2, r))", ...)   # ~1.4x

Xulosa:

  • O'zgartirish/filtr yo'q → konstruktor (dict(), set())
  • O'zgartirish/filtr bor → generator

Xotira:

python
sys.getsizeof([x for x in range(1000)])         # 8,856
sys.getsizeof({x for x in range(1000)})         # 32,984
sys.getsizeof({x: x for x in range(1000)})      # 36,960

set va dict ~4x ko'p — hash jadvali uchun (6.7-dars).

2.7. set/dict generator ifodasi yo'q

Ro'yxat uchun ikki shakl bor:

python
[x for x in r]                          # ro'yxat
(x for x in r)                          # generator ifodasi

set va dict uchun generator ifodasi yo'q — {...} har doim to'liq yaratadi.

Dangasa hisoblash kerak bo'lsa:

python
# ❌ Butun to'plam yaratiladi
if x in {f(y) for y in katta}:
    ...

# ✅ Generator ifodasi bilan
if any(x == f(y) for y in katta):
    ...

# ✅ Yoki to'plamni bir marta quring
KESH = {f(y) for y in katta}
if x in KESH: ...

Bu — 17-darsda batafsil.


3. Tez ma'lumotnoma

Uch generator

python
[IFODA for X in K]              list      takrorlar bor, tartibli
{IFODA for X in K}              set       ⭐ NOYOB, tartibsiz
{KALIT: QIYMAT for X in K}      dict      ⭐ oxirgi kalit g'olib
(IFODA for X in K)              generator (17-dars)

{}                              ⚠️ bo'sh LUG'AT
{x for x in []}                 bo'sh to'plam

Naqshlar

python
{v: k for k, v in d.items()}            invertlash ⚠️ qiymatlar noyob bo'lsin
{k: v for k, v in d.items() if p(v)}    filtrlash
{k: f(v) for k, v in d.items()}         qiymatlarni o'zgartirish
{k.lower(): v for k, v in d.items()}    kalitlarni ⚠️ to'qnashuv
{s: i for i, s in enumerate(r)}         indeks jadvali
{k: v for d in ds for k, v in d.items()}   birlashtirish
{x["shahar"] for x in yozuvlar}         noyob qiymatlar

Konstruktor yetarli bo'lsa

python
{k: v for k, v in juft}     →  dict(juft)          ✅
{k: v for k, v in zip(a,b)} →  dict(zip(a, b))     ✅
{x for x in r}              →  set(r)              ✅
{k: 0 for k in ks}          →  dict.fromkeys(ks, 0) ✅ o'zgarmas qiymat!

O(n²) tuzoqlari

python
{x: r.count(x) for x in set(r)}         ❌ → Counter(r)
{k: [x for x in r if f(x)==k] for k in ...}  ❌ → defaultdict(list)

Tuzoqlar

python
{[x] for x in r}                ❌ unhashable
{v: k ...} qiymat list bo'lsa   ❌ unhashable → tuple(v)
{"a":1,"A":2} → k.lower()       ⚠️ bittasi yo'qoladi
{x: s for x in [1, 1.0, True]}  ⚠️ bitta kalit
set/dict generator ifodasi      ❌ yo'q

4. Batafsil misollar

Misol 1 — Uch generator solishtirilishi

python
"""list, set, dict generatorlari — farqlar."""

import sys

MALUMOT = ["olma", "anor", "olma", "behi", "anor", "olma"]

print("=== 1. Bir xil sintaksis, turli natija ===")

print(f"  MALUMOT = {MALUMOT}\n")

NATIJALAR = [
    ("[s.upper() for s in m]",      [s.upper() for s in MALUMOT]),
    ("{s.upper() for s in m}",      {s.upper() for s in MALUMOT}),
    ("{s: len(s) for s in m}",      {s: len(s) for s in MALUMOT}),
    ("[len(s) for s in m]",         [len(s) for s in MALUMOT]),
    ("{len(s) for s in m}",         {len(s) for s in MALUMOT}),
]

for kod, natija in NATIJALAR:
    tur = type(natija).__name__
    print(f"  {kod:<28} {tur:<6} ({len(natija)}) {natija}")

print("""
  ⭐ list — takrorlar SAQLANADI, tartib bor
     set  — takrorlar YO'QOLADI, tartib yo'q
     dict — kalitlar noyob, oxirgi qiymat g'olib
""")


print("\n=== 2. ⚠️ Bo'sh generator ===")

BOSH = [
    ("[]",              []),
    ("{}",              {}),
    ("set()",           set()),
    ("[x for x in []]", [x for x in []]),
    ("{x for x in []}", {x for x in []}),
    ("{x: x for x in []}", {x: x for x in []}),
]

for kod, q in BOSH:
    print(f"  {kod:<22} {type(q).__name__:<6} {q}")

print(f"\n  ⚠️ {{}} — LUG'AT, to'plam emas!")
print(f"     Bo'sh to'plam: set() yoki {{x for x in []}}")


print("\n=== 3. dict — kalit to'qnashuvi ===")

JUFTLIKLAR = [("a", 1), ("b", 2), ("a", 3), ("c", 4), ("b", 5)]

print(f"  JUFTLIKLAR = {JUFTLIKLAR}\n")

oxirgi = {k: v for k, v in JUFTLIKLAR}
print(f"  {{k: v for k, v in juft}}          → {oxirgi}")
print(f"                                      ⭐ OXIRGISI g'olib")

birinchi = {}
for k, v in JUFTLIKLAR:
    birinchi.setdefault(k, v)
print(f"\n  setdefault bilan (birinchisi)    → {birinchi}")

teskari = {k: v for k, v in reversed(JUFTLIKLAR)}
print(f"  reversed() bilan (birinchisi)     → {teskari}")

from collections import defaultdict
hammasi = defaultdict(list)
for k, v in JUFTLIKLAR:
    hammasi[k].append(v)
print(f"  defaultdict(list) (hammasi)       → {dict(hammasi)}")


print("\n=== 4. Element talablari ===")

SINOVLAR = [
    ("{x for x in range(3)}",           lambda: {x for x in range(3)}),
    ("{[x] for x in range(3)}",         lambda: {[x] for x in range(3)}),
    ("{(x,) for x in range(3)}",        lambda: {(x,) for x in range(3)}),
    ("{frozenset([x]) for x in range(2)}",
     lambda: {frozenset([x]) for x in range(2)}),
    ("{x: x for x in range(3)}",        lambda: {x: x for x in range(3)}),
    ("{[x]: x for x in range(3)}",      lambda: {[x]: x for x in range(3)}),
    ("{x: [x] for x in range(3)}",      lambda: {x: [x] for x in range(3)}),
]

print(f"  {'Ifoda':<38} {'Natija'}")
print("  " + "─" * 66)
for kod, f in SINOVLAR:
    try:
        natija = str(f())[:26]
    except TypeError as x:
        natija = f"❌ {x}"
    print(f"  {kod:<38} {natija}")

print("""
  ⭐ set ELEMENTLARI va dict KALITLARI hashlanishi kerak.
     dict QIYMATLARI — har qanday obyekt.
""")


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

N = 1000
r = [x for x in range(N)]
s = {x for x in range(N)}
d = {x: x for x in range(N)}

print(f"  {N:,} element:\n")
print(f"    list:  {sys.getsizeof(r):>10,} bayt")
print(f"    set:   {sys.getsizeof(s):>10,} bayt  ({sys.getsizeof(s)/sys.getsizeof(r):.1f}x)")
print(f"    dict:  {sys.getsizeof(d):>10,} bayt  ({sys.getsizeof(d)/sys.getsizeof(r):.1f}x)")

print("""
  set va dict ~4x ko'p — hash jadvali bo'sh uyachalari uchun (6.7-dars).
  Evaziga: `in` tekshiruvi O(1) o'rniga O(n).
""")


print("\n=== 6. Tezlik: generator vs konstruktor ===")

import timeit

SOZLASH = """
r = list(range(1000))
juftliklar = [(i, i*2) for i in range(1000)]
a, b = list(range(1000)), list(range(1000, 2000))
"""

SINOVLAR = [
    ("set(r)",                          "set(r)"),
    ("{x for x in r}",                  "{x for x in r}"),
    ("{x for x in r if x % 2}",         "{x for x in r if x % 2}"),
    ("set(filter(lambda x: x%2, r))",   "set(filter(lambda x: x % 2, r))"),
    ("dict(juftliklar)",                "dict(juftliklar)"),
    ("{k: v for k, v in juftliklar}",   "{k: v for k, v in juftliklar}"),
    ("dict(zip(a, b))",                 "dict(zip(a, b))"),
    ("{k: v for k, v in zip(a, b)}",    "{k: v for k, v in zip(a, b)}"),
]

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

print(f"  1000 element × 10 000 marta:\n")
print(f"  {'Ifoda':<34} {'Vaqt':>9}")
print("  " + "─" * 46)
for nom, vaqt in natijalar:
    print(f"  {nom:<34} {vaqt:>7.3f} s")

print("""
  ⭐ Qoida:
     O'zgartirish/filtr YO'Q  → konstruktor (set(), dict())
     O'zgartirish/filtr BOR   → generator
""")

Natijaning muhim qismi:

text
=== 1. Bir xil sintaksis, turli natija ===
  MALUMOT = ['olma', 'anor', 'olma', 'behi', 'anor', 'olma']

  [s.upper() for s in m]       list   (6) ['OLMA', 'ANOR', 'OLMA', 'BEHI', ...]
  {s.upper() for s in m}       set    (3) {'BEHI', 'OLMA', 'ANOR'}
  {s: len(s) for s in m}       dict   (3) {'olma': 4, 'anor': 4, 'behi': 4}
  [len(s) for s in m]          list   (6) [4, 4, 4, 4, 4, 4]
  {len(s) for s in m}          set    (1) {4}

=== 3. dict — kalit to'qnashuvi ===
  {k: v for k, v in juft}          → {'a': 3, 'b': 5, 'c': 4}
                                      ⭐ OXIRGISI g'olib

  setdefault bilan (birinchisi)    → {'a': 1, 'b': 2, 'c': 4}
  defaultdict(list) (hammasi)      → {'a': [1, 3], 'b': [2, 5], 'c': [4]}

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

Misol 2 — Lug'at naqshlari

python
"""dict generatorining amaliy qo'llanishlari."""

from collections import defaultdict, Counter

NARXLAR = {
    "non": 5_000,
    "sut": 12_000,
    "yog'": 45_000,
    "shakar": 8_000,
    "guruch": 15_000,
    "makaron": 9_000,
}

print("=== 1. Filtrlash ===")

FILTRLAR = [
    ("Qiymat > 10 000",
     {k: v for k, v in NARXLAR.items() if v > 10_000}),
    ("Kalit 's' bilan boshlanadi",
     {k: v for k, v in NARXLAR.items() if k.startswith("s")}),
    ("Kalit uzunligi > 4",
     {k: v for k, v in NARXLAR.items() if len(k) > 4}),
    ("Kerakli kalitlar",
     {k: NARXLAR[k] for k in ["non", "sut", "yo'q"] if k in NARXLAR}),
    ("Eng qimmat 3 ta",
     dict(sorted(NARXLAR.items(), key=lambda x: -x[1])[:3])),
]

for nom, natija in FILTRLAR:
    print(f"  {nom:<28} {natija}")


print("\n=== 2. O'zgartirish ===")

OZGARTIRISHLAR = [
    ("15% qimmatlashish",
     {k: round(v * 1.15) for k, v in NARXLAR.items()}),
    ("Ming so'mda",
     {k: v // 1000 for k, v in NARXLAR.items()}),
    ("Formatlangan",
     {k: f"{v:,} so'm" for k, v in NARXLAR.items()}),
    ("Kalitlar katta harfda",
     {k.upper(): v for k, v in NARXLAR.items()}),
    ("Kalit va qiymat birga",
     {k.title(): (v, v > 10_000) for k, v in NARXLAR.items()}),
]

for nom, natija in OZGARTIRISHLAR:
    print(f"\n  {nom}:")
    for k, v in list(natija.items())[:3]:
        print(f"    {k:<12} {v}")
    print(f"    ...")


print("\n\n=== 3. ⭐ Invertlash ===")

d = {"a": 1, "b": 2, "c": 1, "d": 3}
print(f"  d = {d}\n")

teskari = {v: k for k, v in d.items()}
print(f"  {{v: k for k, v in d.items()}}  → {teskari}")
print(f"  ⚠️ 'a' YO'QOLDI — qiymat 1 ikki marta uchradi")

teskari_hammasi = defaultdict(list)
for k, v in d.items():
    teskari_hammasi[v].append(k)
print(f"\n  defaultdict(list) bilan       → {dict(teskari_hammasi)}")
print(f"  ✅ Barcha kalitlar saqlandi")

teskari_toplam = defaultdict(set)
for k, v in d.items():
    teskari_toplam[v].add(k)
print(f"  defaultdict(set) bilan        → {dict(teskari_toplam)}")

print(f"\n  ⚠️ Qiymat hashlanmasa:")
d2 = {"a": [1, 2], "b": [3]}
try:
    {v: k for k, v in d2.items()}
except TypeError as x:
    print(f"    {{v: k for ...}}  →  ❌ {x}")
print(f"    {{tuple(v): k for ...}}  →  "
      f"{ {tuple(v): k for k, v in d2.items()} }  ✅")

print(f"\n  ⚠️ Kalit o'zgartirishda to'qnashuv:")
d3 = {"Ism": 1, "ISM": 2, "ism": 3}
print(f"    d = {d3}")
print(f"    {{k.lower(): v for ...}}  →  { {k.lower(): v for k, v in d3.items()} }")
print(f"    ⚠️ Uchta kalit bittaga aylandi")


print("\n\n=== 4. zip va enumerate bilan ===")

SOZLAR = ["olma", "anor", "behi", "uzum"]
NARXLARI = [5000, 8000, 12000, 20000]

print(f"  Kalit → qiymat:")
print(f"    dict(zip(sozlar, narxlar))              "
      f"{dict(zip(SOZLAR, NARXLARI))}")
print(f"    ⭐ Generator kerak emas")

print(f"\n  Filtr bilan (generator kerak):")
print(f"    {{k: v for k, v in zip(s, n) if v > 8000}}")
print(f"    → { {k: v for k, v in zip(SOZLAR, NARXLARI) if v > 8000} }")

print(f"\n  Indeks jadvali:")
print(f"    {{s: i for i, s in enumerate(sozlar)}}    "
      f"{ {s: i for i, s in enumerate(SOZLAR)} }")
print(f"    {{i: s for i, s in enumerate(sozlar)}}    "
      f"{ {i: s for i, s in enumerate(SOZLAR)} }")

print(f"\n  1 dan boshlab:")
print(f"    { {i: s for i, s in enumerate(SOZLAR, 1)} }")

print(f"\n  Ikki ro'yxatdan tuzilma:")
natija = {s: {"narx": n, "qimmat": n > 10000}
          for s, n in zip(SOZLAR, NARXLARI)}
for k, v in natija.items():
    print(f"    {k:<8} {v}")


print("\n\n=== 5. Ichma-ich generatorlar ===")

print(f"  Ko'paytirish jadvali:")
jadval = {i: {j: i * j for j in range(1, 5)} for i in range(1, 5)}
print(f"       " + "".join(f"{j:>6}" for j in range(1, 5)))
for i, qator in jadval.items():
    print(f"    {i:>2} " + "".join(f"{v:>6}" for v in qator.values()))

print(f"\n  Lug'at ichida ro'yxat:")
harflar = {s: sorted(set(s)) for s in SOZLAR}
for k, v in harflar.items():
    print(f"    {k:<8} {v}")

print(f"\n  Lug'atlarni birlashtirish:")
LUGATLAR = [{"a": 1}, {"b": 2}, {"a": 3, "c": 4}]
birlashgan = {k: v for d in LUGATLAR for k, v in d.items()}
print(f"    {LUGATLAR}")
print(f"    → {birlashgan}")
print(f"    (== {{**d1, **d2, **d3}})")

print(f"\n  Ichma-ichdan barcha kalitlar:")
ICHMA_ICH = {
    "baza": {"host": "x", "port": 1},
    "kesh": {"ttl": 2, "host": "y"},
}
barcha = {k for d in ICHMA_ICH.values() for k in d}
print(f"    {ICHMA_ICH}")
print(f"    → {sorted(barcha)}")


print("\n\n=== 6. ⚠️ O(n²) tuzoqlari ===")

import time
import random

random.seed(1)
KATTA = [random.randrange(100) for _ in range(20_000)]

print(f"  {len(KATTA):,} element, 100 noyob qiymat\n")

# Sanash
boshlandi = time.perf_counter()
n1 = {x: KATTA.count(x) for x in set(KATTA)}
vaqt_yomon = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
n2 = dict(Counter(KATTA))
vaqt_yaxshi = time.perf_counter() - boshlandi

assert n1 == n2
print(f"  Sanash:")
print(f"    {{x: r.count(x) for x in set(r)}}    "
      f"{vaqt_yomon * 1000:>8.1f} ms   O(n·m) ❌")
print(f"    dict(Counter(r))                    "
      f"{vaqt_yaxshi * 1000:>8.1f} ms   O(n)   ✅")
print(f"    Farq: {vaqt_yomon / vaqt_yaxshi:.0f}x")

# Guruhlash
KICHIK = KATTA[:3000]

boshlandi = time.perf_counter()
g1 = {k: [x for x in KICHIK if x % 10 == k] for k in range(10)}
vaqt_yomon = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
g2 = defaultdict(list)
for x in KICHIK:
    g2[x % 10].append(x)
g2 = dict(g2)
vaqt_yaxshi = time.perf_counter() - boshlandi

assert g1 == g2
print(f"\n  Guruhlash ({len(KICHIK):,} element, 10 guruh):")
print(f"    {{k: [x for x in r if f(x)==k] for k in ...}}  "
      f"{vaqt_yomon * 1000:>7.1f} ms  ❌")
print(f"    defaultdict(list) bilan                      "
      f"{vaqt_yaxshi * 1000:>7.1f} ms  ✅")
print(f"    Farq: {vaqt_yomon / vaqt_yaxshi:.0f}x")

print("""
  ⭐ Qoida: generator BIR MARTA o'tish uchun.
     Har element uchun butun ketma-ketlikni qayta ko'rish —
     O(n²), boshqa yechim kerak.
""")

Natijaning muhim qismi:

text
=== 3. ⭐ Invertlash ===
  d = {'a': 1, 'b': 2, 'c': 1, 'd': 3}

  {v: k for k, v in d.items()}  → {1: 'c', 2: 'b', 3: 'd'}
  ⚠️ 'a' YO'QOLDI — qiymat 1 ikki marta uchradi

  defaultdict(list) bilan       → {1: ['a', 'c'], 2: ['b'], 3: ['d']}
  ✅ Barcha kalitlar saqlandi

=== 6. ⚠️ O(n²) tuzoqlari ===
  20,000 element, 100 noyob qiymat

  Sanash:
    {x: r.count(x) for x in set(r)}       184.2 ms   O(n·m) ❌
    dict(Counter(r))                        1.8 ms   O(n)   ✅
    Farq: 102x

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

Misol 3 — set generatori

python
"""set generatorining amaliy qo'llanishlari."""

import re
from collections import Counter

YOZUVLAR = [
    {"id": 1, "ism": "Aziz", "shahar": "Toshkent", "teglar": ["python", "veb"]},
    {"id": 2, "ism": "Bobur", "shahar": "Samarqand", "teglar": ["java"]},
    {"id": 3, "ism": "Aziza", "shahar": "Toshkent", "teglar": ["python", "api"]},
    {"id": 4, "ism": "Dilnoza", "shahar": "Buxoro", "teglar": []},
    {"id": 5, "ism": "Eldor", "shahar": "Toshkent", "teglar": ["veb", "api"]},
]

print("=== 1. Noyob qiymatlar ===")

NOYOB = [
    ("Shaharlar",       {x["shahar"] for x in YOZUVLAR}),
    ("Barcha teglar",   {t for x in YOZUVLAR for t in x["teglar"]}),
    ("Ism birinchi harflari", {x["ism"][0] for x in YOZUVLAR}),
    ("Ism uzunliklari", {len(x["ism"]) for x in YOZUVLAR}),
    ("Teglari bor ID lar", {x["id"] for x in YOZUVLAR if x["teglar"]}),
]

for nom, natija in NOYOB:
    print(f"  {nom:<24} {sorted(natija)}")


print("\n=== 2. To'plam amallari bilan ===")

toshkent = {x["id"] for x in YOZUVLAR if x["shahar"] == "Toshkent"}
python_bilan = {x["id"] for x in YOZUVLAR if "python" in x["teglar"]}
tegsiz = {x["id"] for x in YOZUVLAR if not x["teglar"]}

print(f"  Toshkentdagilar:    {sorted(toshkent)}")
print(f"  Python bilan:       {sorted(python_bilan)}")
print(f"  Tegsiz:             {sorted(tegsiz)}\n")

print(f"  Toshkent VA python: {sorted(toshkent & python_bilan)}")
print(f"  Toshkent YOKI python: {sorted(toshkent | python_bilan)}")
print(f"  Toshkent, python siz: {sorted(toshkent - python_bilan)}")
print(f"  Faqat bittasida:    {sorted(toshkent ^ python_bilan)}")

print(f"\n  Teg juftliklari (birga uchraydiganlar):")
juftliklar = {
    frozenset({a, b})
    for x in YOZUVLAR
    for i, a in enumerate(x["teglar"])
    for b in x["teglar"][i + 1:]
}
for j in sorted(juftliklar, key=lambda s: sorted(s)):
    print(f"    {' + '.join(sorted(j))}")


print("\n=== 3. Matn tahlili ===")

MATN = """
Python dasturlash tili — oddiy va kuchli. Python o'rganish oson.
Dasturlash — bu ijod. Python bilan ijod qilish qiziq!
"""

sozlar = [s.lower().strip(".,!—") for s in MATN.split()]
sozlar = [s for s in sozlar if s]

noyob = {s for s in sozlar}
uzunlar = {s for s in noyob if len(s) > 6}
apostrofli = {s for s in noyob if "'" in s}
harflar = {c for s in noyob for c in s if c.isalpha()}

print(f"  Jami so'zlar:    {len(sozlar)}")
print(f"  Noyob:           {len(noyob)}")
print(f"  Uzun (>6):       {sorted(uzunlar)}")
print(f"  Apostrofli:      {sorted(apostrofli)}")
print(f"  Noyob harflar:   {len(harflar)} — {''.join(sorted(harflar))}")

print(f"\n  Faqat bir marta uchraganlar:")
hisob = Counter(sozlar)
bir_martalik = {s for s, n in hisob.items() if n == 1}
print(f"    {len(bir_martalik)} ta: {sorted(bir_martalik)[:6]}...")

print(f"\n  Bir necha marta:")
takroriy = {s for s, n in hisob.items() if n > 1}
for s in sorted(takroriy):
    print(f"    {s:<14} {'█' * hisob[s]} {hisob[s]}")


print("\n=== 4. Validatsiya ===")

XOM_EMAILLAR = [
    "Aziz@Mail.uz", "aziz@mail.uz", "  bobur@mail.uz  ",
    "BOBUR@MAIL.UZ", "notogri", "aziza@mail.uz", "", "@mail.uz",
]

NAQSH = re.compile(r"[\w.+-]+@[\w-]+\.[\w.]+")

toza = {e.strip().lower() for e in XOM_EMAILLAR
        if NAQSH.fullmatch(e.strip().lower())}
notogri = {e for e in XOM_EMAILLAR
           if not NAQSH.fullmatch(e.strip().lower())}
domenlar = {e.split("@")[1] for e in toza}

print(f"  Xom:        {len(XOM_EMAILLAR)}")
print(f"  Noyob toza: {len(toza)}")
print(f"  Noto'g'ri:  {len(notogri)}\n")

for e in sorted(toza):
    print(f"    ✅ {e}")
print()
for e in sorted(notogri, key=str):
    print(f"    ❌ {e!r}")

print(f"\n  Domenlar: {sorted(domenlar)}")


print("\n=== 5. ⚠️ Tartib yo'q ===")

MALUMOT = ["z", "a", "m", "b", "a"]

print(f"  MALUMOT = {MALUMOT}\n")
print(f"  {{x for x in m}}                → {({x for x in MALUMOT})}")
print(f"                                  ⚠️ tartib aniqlanmagan")
print(f"  sorted({{x for x in m}})         → {sorted({x for x in MALUMOT})}")
print(f"  list(dict.fromkeys(m))         → {list(dict.fromkeys(MALUMOT))}")
print(f"                                  ⭐ noyob + ASL tartib")

print("""
  ⭐ Uch variant:
     {x for x in m}           noyob, tartibsiz, tez
     sorted({x for x in m})   noyob, saralangan
     list(dict.fromkeys(m))   noyob, ASL tartibda
""")


print("\n=== 6. Ichma-ich va shartli ===")

MATRITSA = [[1, -2, 3], [-4, 5, -6], [7, -8, 9]]

print(f"  MATRITSA = {MATRITSA}\n")

AMALLAR = [
    ("Barcha noyob qiymatlar",
     {x for qator in MATRITSA for x in qator}),
    ("Musbatlar",
     {x for qator in MATRITSA for x in qator if x > 0}),
    ("Absolyut qiymatlar",
     {abs(x) for qator in MATRITSA for x in qator}),
    ("Belgilar",
     {"musbat" if x > 0 else "manfiy" for qator in MATRITSA for x in qator}),
    ("Qator yig'indilari",
     {sum(qator) for qator in MATRITSA}),
    ("Koordinatalar (musbat)",
     {(i, j) for i, qator in enumerate(MATRITSA)
      for j, x in enumerate(qator) if x > 0}),
]

for nom, natija in AMALLAR:
    print(f"  {nom:<26} {sorted(natija, key=str)}")

print(f"\n  ⭐ Koordinatalar to'plami — grafik/o'yin algoritmlarida asosiy naqsh")
print(f"     (tuple hashlanadi — 6.5-dars)")

Natijaning muhim qismi:

text
=== 2. To'plam amallari bilan ===
  Toshkentdagilar:    [1, 3, 5]
  Python bilan:       [1, 3]

  Toshkent VA python: [1, 3]
  Toshkent, python siz: [5]
  Faqat bittasida:    [5]

  Teg juftliklari (birga uchraydiganlar):
    api + python
    api + veb
    python + veb

=== 5. ⚠️ Tartib yo'q ===
  MALUMOT = ['z', 'a', 'm', 'b', 'a']

  {x for x in m}                → {'m', 'z', 'a', 'b'}
                                  ⚠️ tartib aniqlanmagan
  sorted({x for x in m})         → ['a', 'b', 'm', 'z']
  list(dict.fromkeys(m))         → ['z', 'a', 'm', 'b']
                                  ⭐ noyob + ASL tartib

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

Misol 4 — Amaliy: ma'lumot indeksatori

python
"""set va dict generatorlari bilan to'liq vosita."""

from collections import defaultdict, Counter
from dataclasses import dataclass

print("=== Maqolalar indeksatori ===\n")


@dataclass(frozen=True)
class Maqola:
    id: int
    sarlavha: str
    muallif: str
    teglar: frozenset
    ball: int
    yil: int


MAQOLALAR = [
    Maqola(1, "Python asoslari",     "Aziz",    frozenset({"python", "boshlangich"}), 95, 2025),
    Maqola(2, "Django darsligi",     "Bobur",   frozenset({"python", "django", "veb"}), 88, 2026),
    Maqola(3, "React komponentlari", "Aziza",   frozenset({"javascript", "react", "veb"}), 92, 2026),
    Maqola(4, "Algoritmlar",         "Aziz",    frozenset({"algoritm", "boshlangich"}), 78, 2024),
    Maqola(5, "FastAPI qo'llanma",   "Dilnoza", frozenset({"python", "api", "veb"}), 90, 2026),
    Maqola(6, "TypeScript",          "Aziza",   frozenset({"javascript", "typescript"}), 85, 2025),
]


class Indeks:
    """dict va set generatorlari bilan qurilgan indeks."""

    def __init__(self, maqolalar):
        self.maqolalar = {m.id: m for m in maqolalar}       # ⭐ dict generator

        # Teg → maqola ID lari
        self.teg_indeksi = defaultdict(set)
        for m in maqolalar:
            for t in m.teglar:
                self.teg_indeksi[t].add(m.id)

        # Muallif → maqola ID lari
        self.muallif_indeksi = defaultdict(set)
        for m in maqolalar:
            self.muallif_indeksi[m.muallif].add(m.id)

        # Yil → maqola ID lari
        self.yil_indeksi = defaultdict(set)
        for m in maqolalar:
            self.yil_indeksi[m.yil].add(m.id)

    @property
    def barcha_teglar(self) -> set:
        return {t for m in self.maqolalar.values() for t in m.teglar}

    @property
    def barcha_mualliflar(self) -> set:
        return {m.muallif for m in self.maqolalar.values()}

    @property
    def yillar(self) -> set:
        return {m.yil for m in self.maqolalar.values()}

    def teglar_bilan(self, *teglar, rejim="and") -> set:
        toplamlar = [self.teg_indeksi.get(t, set()) for t in teglar]
        if not toplamlar:
            return set()
        return (set.intersection(*toplamlar) if rejim == "and"
                else set().union(*toplamlar))

    def teg_statistikasi(self) -> dict:
        return {t: len(ids) for t, ids in self.teg_indeksi.items()}

    def muallif_ballari(self) -> dict:
        return {
            muallif: {
                "soni": len(ids),
                "ortacha": sum(self.maqolalar[i].ball for i in ids) // len(ids),
                "eng_yaxshi": max(self.maqolalar[i].ball for i in ids),
            }
            for muallif, ids in self.muallif_indeksi.items()
        }

    def teg_juftliklari(self) -> Counter:
        return Counter(
            frozenset({a, b})
            for m in self.maqolalar.values()
            for i, a in enumerate(sorted(m.teglar))
            for b in sorted(m.teglar)[i + 1:]
        )

    def teg_qamrovi(self) -> dict:
        """Qaysi teg boshqasini o'z ichiga oladi."""
        return {
            (a, b): True
            for a in self.teg_indeksi
            for b in self.teg_indeksi
            if a != b and self.teg_indeksi[a] < self.teg_indeksi[b]
        }


ind = Indeks(MAQOLALAR)

print("=== 1. Indekslar ===\n")

print(f"  Maqolalar:  {len(ind.maqolalar)}")
print(f"  Mualliflar: {sorted(ind.barcha_mualliflar)}")
print(f"  Yillar:     {sorted(ind.yillar)}")
print(f"  Teglar:     {sorted(ind.barcha_teglar)}\n")

print(f"  Teg indeksi:")
for teg in sorted(ind.teg_indeksi):
    ids = sorted(ind.teg_indeksi[teg])
    print(f"    {teg:<14} {ids}")


print("\n\n=== 2. Qidiruv ===\n")

SOROVLAR = [
    (("python",), "and"),
    (("python", "veb"), "and"),
    (("python", "veb"), "or"),
    (("javascript", "python"), "and"),
    (("javascript", "python"), "or"),
]

for teglar, rejim in SOROVLAR:
    natija = ind.teglar_bilan(*teglar, rejim=rejim)
    print(f"  {rejim.upper():<4} {str(list(teglar)):<28} → {len(natija)} maqola")
    for i in sorted(natija):
        print(f"         • {ind.maqolalar[i].sarlavha}")
    print()


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

stat = ind.teg_statistikasi()
eng_kop = max(stat.values())

print(f"  Teg mashhurligi:")
for teg, n in sorted(stat.items(), key=lambda x: (-x[1], x[0])):
    print(f"    {teg:<14} {'█' * (n * 20 // eng_kop)} {n}")

print(f"\n  Muallif statistikasi:")
print(f"    {'Muallif':<12} {'Soni':>5} {'O`rtacha':>10} {'Eng yaxshi':>12}")
print("    " + "─" * 42)
for muallif, m in sorted(ind.muallif_ballari().items(),
                         key=lambda x: -x[1]["ortacha"]):
    print(f"    {muallif:<12} {m['soni']:>5} {m['ortacha']:>10} {m['eng_yaxshi']:>12}")


print("\n\n=== 4. Teglar bog'liqligi ===\n")

juftliklar = ind.teg_juftliklari()
print(f"  Birga uchraydigan teglar:")
for j, n in juftliklar.most_common(6):
    a, b = sorted(j)
    print(f"    {a:<14} + {b:<14} {'█' * n} {n}")

qamrov = ind.teg_qamrovi()
print(f"\n  Teg iyerarxiyasi (avtomatik aniqlangan):")
if qamrov:
    for (a, b) in sorted(qamrov):
        na, nb = len(ind.teg_indeksi[a]), len(ind.teg_indeksi[b])
        print(f"    «{a}» ⊂ «{b}»   ({na} ⊂ {nb} maqola)")
else:
    print(f"    (topilmadi)")


print("\n\n=== 5. Kesishmalar matritsasi ===\n")

teglar = sorted(ind.barcha_teglar)
matritsa = {
    (a, b): len(ind.teg_indeksi[a] & ind.teg_indeksi[b])
    for a in teglar for b in teglar
}

w = max(len(t) for t in teglar)
print(f"    {'':<{w}} " + "".join(f"{t[:4]:>6}" for t in teglar))
for a in teglar:
    qator = f"    {a:<{w}} "
    for b in teglar:
        n = matritsa[(a, b)]
        qator += f"{n if n else '·':>6}"
    print(qator)

print(f"\n  ⭐ Diagonal — har tegning maqolalari soni")
print(f"     Boshqa katakchalar — kesishma")


print("\n\n=== 6. Turli guruhlashlar ===\n")

GURUHLASHLAR = [
    ("Yil bo'yicha soni",
     {y: len(ids) for y, ids in sorted(ind.yil_indeksi.items())}),
    ("Yil bo'yicha o'rtacha ball",
     {y: sum(ind.maqolalar[i].ball for i in ids) // len(ids)
      for y, ids in sorted(ind.yil_indeksi.items())}),
    ("Muallif → teglar",
     {muallif: sorted({t for i in ids for t in ind.maqolalar[i].teglar})
      for muallif, ids in sorted(ind.muallif_indeksi.items())}),
    ("Ball diapazoni → maqolalar",
     {f"{d}0-{d}9": sorted({m.id for m in MAQOLALAR if m.ball // 10 == d})
      for d in sorted({m.ball // 10 for m in MAQOLALAR})}),
]

for nom, natija in GURUHLASHLAR:
    print(f"  {nom}:")
    for k, v in natija.items():
        print(f"    {str(k):<12} {v}")
    print()


print("=== 7. Ishlatilgan naqshlar ===\n")

print("""
  {m.id: m for m in maqolalar}                    dict generator — indeks
  {t for m in maqolalar for t in m.teglar}        set generator — noyob teglar
  {t: len(ids) for t, ids in indeks.items()}      statistika
  {muallif: {...} for muallif, ids in ...}        ichma-ich dict
  {frozenset({a,b}) for ...}                      tartibsiz juftliklar 6.9-bob
  {(a,b): n for a in ts for b in ts}              matritsa
  set.intersection(*toplamlar)                    ko'p to'plam 6.8-bob
  defaultdict(set)                                indeks qurish

  ⭐ Har vazifa uchun to'g'ri tuzilma —
     kodni qisqa VA tez qiladi.
""")

Natijaning muhim qismi:

text
=== 2. Qidiruv ===

  AND  ['python', 'veb']              → 2 maqola
         • Django darsligi
         • FastAPI qo'llanma

  OR   ['javascript', 'python']       → 5 maqola

=== 4. Teglar bog'liqligi ===

  Birga uchraydigan teglar:
    veb            + python         ██ 2
    api            + python         █ 1

  Teg iyerarxiyasi (avtomatik aniqlangan):
    «django» ⊂ «python»   (1 ⊂ 3 maqola)
    «api» ⊂ «python»   (1 ⊂ 3 maqola)
    «react» ⊂ «javascript»   (1 ⊂ 2 maqola)

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


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

Noto'g'ri fikr To'g'risi
"{} — bo'sh to'plam generatori" Lug'at
"dict generatorida birinchi kalit qoladi" Oxirgisi g'olib
"Invertlash har doim ishlaydi" Qiymatlar noyob va hashlanadigan bo'lsin
"{k: v for k, v in juft} yaxshi uslub" dict(juft) — soddaroq va tezroq
"{x: r.count(x) for x in set(r)} normal" O(n²). Counter(r)
"set generatorida tartib bor" Tartibsiz
"(x for x in r) — tuple generatori" Generator ifodasi
"set/dict uchun generator ifodasi bor" Yo'q — {...} to'liq yaratadi
"Kalit o'zgartirish xavfsiz" To'qnashuv bo'lishi mumkin

6. Keng tarqalgan xatolar va yechimlari

1. Bo'sh to'plam

python
s = {}                                  # ❌ dict
s = set()                               # ✅

2. Invertlashda yo'qotish

python
{v: k for k, v in d.items()}            # ⚠️ takroriy qiymatlar

teskari = defaultdict(list)             # ✅
for k, v in d.items():
    teskari[v].append(k)

3. Ortiqcha generator

python
{k: v for k, v in juftliklar}           # ⚠️
dict(juftliklar)                        # ✅

{x for x in r}                          # ⚠️
set(r)                                  # ✅

4. O(n²) sanash

python
{x: r.count(x) for x in set(r)}         # ❌
dict(Counter(r))                        # ✅

5. O(n²) guruhlash

python
{k: [x for x in r if f(x) == k] for k in {f(x) for x in r}}     # ❌

guruhlar = defaultdict(list)            # ✅
for x in r: guruhlar[f(x)].append(x)

6. Hashlanmaydigan element/kalit

python
{[x] for x in r}                        # ❌
{tuple(x) for x in r}                   # ✅

{v: k for k, v in d.items()}            # ❌ v — list bo'lsa
{tuple(v): k for k, v in d.items()}     # ✅

7. fromkeys o'zgaruvchan qiymat bilan

python
dict.fromkeys(kalitlar, [])             # ❌ bitta ro'yxat
{k: [] for k in kalitlar}               # ✅

8. Tartib kutish

python
list({x for x in r})[0]                 # ⚠️ nomustaqil
sorted({x for x in r})[0]               # ✅
list(dict.fromkeys(r))[0]               # ✅ asl tartib

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 6.15-dars (o'tilgan): ro'yxat generatori — bir xil sintaksis
  • 6.17-dars: generator ifodalari
  • 6.7, 6.8-darslar (o'tilgan): set va to'plam amallari
  • 6.10, 6.11-darslar (o'tilgan): dict, Counter, defaultdict
  • 6.13-dars (o'tilgan): hashlanish talabi
  • 7-qism: lambda, funksiyalar
  • 10-qism: funksional dasturlash

8. Eng yaxshi amaliyotlar

  1. O'zgartirish yo'q bo'lsa konstruktor. set(r), dict(juft), dict(zip(a, b)).

  2. Invertlashda qiymatlar noyobligini tekshiring. Aks holda defaultdict(list).

  3. Sanash — Counter, guruhlash — defaultdict. Generator O(n²) qiladi.

  4. set tartibiga tayanmang. sorted() yoki dict.fromkeys().

  5. Noyob qiymatlar uchun set generatori. {x["maydon"] for x in yozuvlar} — idiomatik.

  6. Bo'sh to'plam — set(). {} — lug'at.

  7. Kalit o'zgartirishda to'qnashuvni tekshiring. len(natija) != len(asl) bo'lsa yo'qotish bor.

  8. Ichma-ich generatorlarni chegaralang. Ikki darajadan ko'p bo'lsa funksiya ajrating.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
1.  print(type({}))
2.  print(type({x for x in []}))
3.  print({x % 3 for x in range(10)})
4.  print({k: v for k, v in [("a",1),("a",2)]})
5.  print(len({s.upper() for s in ["a","A","b"]}))
6.  print({v: k for k, v in {"a":1,"b":1}.items()})
7.  print({x: [x] for x in range(2)})
8.  print({[x]: x for x in range(2)})
9.  print({k.lower(): v for k, v in {"A":1,"a":2}.items()})
10. print({s: i for i, s in enumerate("abc")})
11. print(dict(zip("abc", range(3))) == {c: i for i, c in enumerate("abc")})
12. print({x: x for x in [1, 1.0, True]})
Javoblar
  1. <class 'dict'>
  2. <class 'set'>
  3. {0, 1, 2}
  4. {'a': 2} — oxirgisi
  5. 2 — 'A' va 'B'
  6. {1: 'b'} — 'a' yo'qoldi
  7. {0: [0], 1: [1]} — qiymat list bo'lishi mumkin
  8. TypeError — kalit list
  9. {'a': 2} — to'qnashuv
  10. {'a': 0, 'b': 1, 'c': 2}
  11. True
  12. {1: True} — bitta kalit

Vazifa 2: Xatolarni tuzating

python
1.  s = {}
2.  hisob = {x: r.count(x) for x in set(r)}
3.  teskari = {v: k for k, v in d.items()}   # barcha kalitlar kerak
4.  d = {k: v for k, v in juftliklar}
5.  guruh = {k: [x for x in r if f(x)==k] for k in {f(x) for x in r}}
6.  d = dict.fromkeys(kalitlar, [])
7.  birinchi = list({x for x in r})[0]
8.  teskari = {v: k for k, v in {"a": [1,2]}.items()}
Javoblar
python
1.  s = set()
2.  hisob = dict(Counter(r))
3.  teskari = defaultdict(list)
    for k, v in d.items(): teskari[v].append(k)
4.  d = dict(juftliklar)
5.  guruh = defaultdict(list)
    for x in r: guruh[f(x)].append(x)
6.  d = {k: [] for k in kalitlar}
7.  birinchi = sorted({x for x in r})[0]    # yoki min()
8.  teskari = {tuple(v): k for k, v in d.items()}

Vazifa 3: Lug'at vositalari

Funksiyalar yozing (generatorlar bilan):

  1. invert(d) — barcha kalitlarni saqlab invertlash
  2. filtrla(d, kalit=None, qiymat=None) — ikki mezon bilan
  3. xarita(d, kalit_f=None, qiymat_f=None) — o'zgartirish
  4. tanla(d, *kalitlar) — faqat berilgan kalitlar
  5. chiqar(d, *kalitlar) — berilganlarsiz
  6. guruhla(r, kalit_f) — defaultdict bilan
  7. Har biri uchun to'qnashuv ogohlantirishi

Vazifa 4: Ma'lumot profillovchi

Yozuvlar ro'yxati uchun:

  1. Har maydon uchun noyob qiymatlar (set generator)
  2. Har maydon uchun turlar
  3. Bo'sh/None qiymatlar soni
  4. Kardinallik (noyob/jami nisbati)
  5. Maydonlar orasidagi bog'liqlik (bir maydon boshqasini aniqlaydimi)
  6. Nomzod birlamchi kalitlar (noyob maydonlar)

Vazifa 5: Indeks tizimi

4-misolni kengaytiring:

  1. Ko'p maydonli indeks (teg + yil + muallif)
  2. Diapazon bo'yicha qidiruv (ball 80-90)
  3. Matn qidiruvi (sarlavhada so'z)
  4. Tavsiya (o'xshash maqolalar — Jaccard)
  5. Faset qidiruv (har filtr uchun natijalar soni)
  6. Kesh (frozenset kalit bilan)

Vazifa 6: Tezlik tadqiqoti

Solishtiring va grafik chizing:

  1. {x for x in r} vs set(r) vs set(map(f, r))
  2. {k: v for ...} vs dict(...) vs dict.fromkeys(...)
  3. Counter(r) vs {x: r.count(x) ...} — turli hajmda
  4. defaultdict(list) vs generator guruhlash
  5. set vs frozenset yaratish
  6. Xotira sarfi

Vazifa 7: O'ylash

Nega Pythonda set va dict uchun generator ifodasi yo'q ((x for x in r) ro'yxat uchun bo'lgani kabi)?

Javob

Chunki generator ifodasi — turdan mustaqil oqim.

Nima bor:

python
[x for x in r]              # list yaratadi
{x for x in r}              # set yaratadi
{k: v for k, v in r}        # dict yaratadi
(x for x in r)              # GENERATOR yaratadi

To'rtinchisi — boshqa toifadagi narsa. U hech qanday konteyner yaratmaydi, balki oqim (iterator) qaytaradi.

Nega "set generator ifodasi" ma'nosiz:

Generator — dangasa, ketma-ket oqim. Uning asosiy xususiyatlari:

  • Bir marta o'tiladi
  • Xotirada faqat joriy element
  • len() yo'q, indeks yo'q

set ning asosiy xususiyati esa — noyoblik. Noyoblikni ta'minlash uchun barcha ko'rilgan elementlarni eslab qolish kerak:

python
# "Dangasa set" tasavvur qiling:
korilgan = set()
for x in manba:
    if x not in korilgan:       # ⚠️ to'plam baribir xotirada
        korilgan.add(x)
        yield x

Ya'ni xotira baribir O(n) — generatorning asosiy foydasi yo'qoladi.

Bu naqsh mavjud, lekin boshqa nom bilan:

python
from itertools import filterfalse

def noyob(iterable):
    korilgan = set()
    for x in iterable:
        if x not in korilgan:
            korilgan.add(x)
            yield x

# yoki tayyor:
from more_itertools import unique_everseen

Bu — generator, lekin u set emas. U tartibni saqlaydi va oqim sifatida ishlaydi.

dict uchun ham xuddi shunday:

Dangasa lug'at nima degani? Kalit bo'yicha murojaat uchun barcha kalitlar xotirada bo'lishi kerak. Aks holda d[k] ishlamaydi.

Lekin oqim sifatida juftliklar — mavjud:

python
((k, f(v)) for k, v in d.items())       # ✅ generator ifodasi
dict((k, f(v)) for k, v in d.items())   # ✅ to'liq lug'at
{k: f(v) for k, v in d.items()}         # ✅ soddaroq

Ya'ni generator ifodasi allaqachon bor — u shunchaki tuple lar oqimini beradi, va dict() uni lug'atga aylantiradi.

Sintaksis nuqtai nazaridan:

python
{x for x in r}              # set literal sintaksisi ichida generator
{k: v for k, v in r}        # dict literal sintaksisi ichida generator
[x for x in r]              # list literal sintaksisi ichida generator
(x for x in r)              # qavs — GURUHLASH, konteyner emas

() konteyner literali emas (tuple ni vergul yaratadi — 6.5-dars). Shuning uchun () "bo'sh" qoldi va generator ifodasi uchun ishlatildi.

Agar () tuple literali bo'lganda, generator ifodasi uchun boshqa sintaksis kerak bo'lardi.

Tarixiy tartib:

  • Python 2.0 — list comprehension (PEP 202)
  • Python 2.4 — generator expression (PEP 289)
  • Python 2.7 / 3.0 — set va dict comprehension (PEP 274)

Generator ifodasi set/dict generatorlaridan oldin paydo bo'lgan. Va u umumiy vosita sifatida loyihalangan:

python
sum(x for x in r)
max(x for x in r)
any(x for x in r)
set(x for x in r)               # ✅ ishlaydi!
dict((k, v) for k, v in r)      # ✅ ishlaydi!

Ya'ni set(genexp) va dict(genexp) allaqachon bor edi. {x for x in r} — shunchaki qisqaroq yozuv (syntactic sugar).

Amaliy xulosa:

python
# Dangasa oqim kerak
gen = (f(x) for x in katta)
birinchi_mos = next(x for x in gen if shart(x))      # ✅ erta to'xtash

# Noyoblik + dangasalik kerak
def noyob(it):
    korilgan = set()
    for x in it:
        if x not in korilgan:
            korilgan.add(x); yield x

# To'liq to'plam kerak
{f(x) for x in r}

Xulosa: "set generator ifodasi" yo'q, chunki u mantiqan qarama-qarshi: set — to'liq materiallashgan konteyner, generator — dangasa oqim. Ular birga bo'la olmaydi.

Nimani mustahkamlaydi: 2.1, 2.2, 2.7-bo'limlar.


Xulosa

Bu darsda set va dict generatorlarini o'rgandik.

Eng muhim uch fikr:

  1. Bir xil sintaksis, turli semantika. {...} set beradi (noyob, tartibsiz), {k: v ...} dict beradi (kalitlar noyob, oxirgi qiymat g'olib). Va {} — bo'sh lug'at, to'plam emas.

  2. Invertlash ehtiyot talab qiladi. {v: k for k, v in d.items()} qiymatlar takrorlansa kalitlarni yo'qotadi, hashlanmasa xato beradi. Barcha kalitlar kerak bo'lsa — defaultdict(list).

  3. Generator — bir marta o'tish uchun. {x: r.count(x) for x in set(r)} va shunga o'xshash naqshlar O(n²). Sanash — Counter, guruhlash — defaultdict.

Keyingi darsda generator ifodalarini ko'ramiz: (x for x in r) — dangasa hisoblash, cheksiz oqimlar va xotira tejashning asosiy vositasi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
6.16-dars: dict va set generatorlari — IlmHamroh