2-qism · Ma'lumot tuzilmalari va funksiyalar·06-bob
Lug'atlar, to'plamlar va collections moduli
dict va set qanday ishlaydi (hash jadval), hashlanish nima, eng muhim metodlar va idiomalar, Counter, defaultdict, deque, namedtuple — va qachon qaysi tuzilmani tanlash.
Agar ro'yxat Python'ning eng ko'p ishlatiladigan tuzilmasi bo'lsa, lug'at
(dict) — eng muhimi. Python'ning o'zi lug'atlar ustiga qurilgan:
modul atributlari, klass atributlari, funksiya argumentlari (**kwargs) —
hammasi ichkarida lug'at. JSON — lug'at. API so'rov va javoblari — lug'at.
Model konfiguratsiyasi — lug'at. Bu bob — Python'ni haqiqatan
tushunishning yarim yo'li.
Lug'atlar bilan ishlash: kalitlar, get, update, aylanish. collections moduli (Counter, defaultdict, deque) — bobning 7-bo'limida.
1. Lug'at asoslari#
Lug'at — kalit → qiymat juftliklari to'plami:
talaba = {
"ism": "Aziz",
"yosh": 21,
"kurslar": ["Python", "ML"],
}
talaba["ism"] # 'Aziz'
talaba["yosh"] = 22 # o'zgartirish
talaba["shahar"] = "Buxoro" # yangi kalit qo'shish
del talaba["kurslar"] # o'chirish
"ism" in talaba # True — KALITLAR orasidan qidiradi
len(talaba) # 3Yaratishning boshqa usullari:
dict(ism="Aziz", yosh=21) # kalitlar oddiy nom bo'lsa
dict(zip(["a", "b"], [1, 2])) # {'a': 1, 'b': 2}
dict.fromkeys(["a", "b"], 0) # {'a': 0, 'b': 0}
{x: x ** 2 for x in range(4)} # {0: 0, 1: 1, 2: 4, 3: 9} — dict comprehension (7-bob)Tartib#
Python 3.7'dan boshlab lug'at qo'shilish tartibini saqlaydi — bu til
kafolati. {"b": 2, "a": 1} aylanilganda avval "b", keyin "a" keladi.
2. Ichki tuzilish: hash jadval#
Nega talaba["ism"] lug'atda 10 ta yoki 10 million element bo'lishidan
qat'i nazar bir xil tez ishlaydi? Javob — hash jadval.
- Python kalitdan
hash()funksiyasi orqali son hisoblaydi. - Shu sondan jadvaldagi katak raqamini topadi.
- To'g'ridan-to'g'ri o'sha katakka boradi — qidirish shart emas.
Natijada qidirish, qo'shish va o'chirish o'rtacha O(1) — ro'yxatdagi
in (O(n)) bilan solishtiring.
Hashlanish (hashability)#
Bundan muhim qoida kelib chiqadi: kalit hashlanadigan (hashable) bo'lishi kerak, ya'ni:
hash(kalit)hisoblanishi mumkin;- kalit hayoti davomida hash qiymati o'zgarmasligi kerak.
Shuning uchun immutable tiplar kalit bo'la oladi, mutable tiplar — yo'q:
| Kalit bo'la oladi | Kalit bo'la olmaydi |
|---|---|
int, float, str, bytes, bool, None | list |
tuple (ichidagilar ham hashable bo'lsa) | dict |
frozenset | set |
koordinatalar = {(41.31, 69.24): "Toshkent", (39.65, 66.96): "Samarqand"} # ✅ tuple kalit
kesh = {[1, 2]: "x"} # ❌ TypeError: unhashable type: 'list'Agar ro'yxat kalit bo'lishi mumkin bo'lganda va siz uni o'zgartirsangiz, uning hashi o'zgarar va lug'at uni "yo'qotib" qo'yardi. Python buni oldindan taqiqlaydi.
3. Xavfsiz o'qish: get, setdefault, pop#
Mavjud bo'lmagan kalitni o'qish — KeyError:
config = {"model": "claude-opus-5-5"}
config["temperature"] # KeyError: 'temperature'Xavfsiz usullar:
config.get("temperature") # None
config.get("temperature", 1.0) # 1.0 — standart qiymat
config.pop("model") # qiymatni olib, kalitni o'chiradi
config.pop("yo'q", None) # yo'q bo'lsa — None, xato emas
config.setdefault("tags", []).append("test") # yo'q bo'lsa yaratib, qiymatini qaytaradiEAFP va LBYL#
Python'da ikki uslub bor:
# LBYL — "Look Before You Leap" (sakrashdan oldin qara)
if "temperature" in config:
t = config["temperature"]
else:
t = 1.0
# EAFP — "Easier to Ask Forgiveness than Permission" (ruxsat so'ragandan kechirim so'rash oson)
try:
t = config["temperature"]
except KeyError:
t = 1.0
# Ko'pincha eng yaxshisi — maxsus metod:
t = config.get("temperature", 1.0)Python jamiyati EAFP uslubini ko'proq qo'llaydi (10-bobda batafsil),
lekin lug'atlar uchun get ko'pincha eng toza yechim.
4. Aylanish va ko'rinishlar (views)#
narxlar = {"olma": 12000, "nok": 15000, "uzum": 22000}
narxlar.keys() # dict_keys(['olma', 'nok', 'uzum'])
narxlar.values() # dict_values([12000, 15000, 22000])
narxlar.items() # dict_items([('olma', 12000), ...])
for meva, narx in narxlar.items():
print(f"{meva:<6} {narx:>7,} so'm")keys(), values(), items() — nusxa emas, jonli ko'rinish (view):
lug'at o'zgarsa, ular ham o'zgaradi. keys() va items() to'plam
amallarini ham qo'llaydi:
a = {"x": 1, "y": 2}
b = {"y": 3, "z": 4}
a.keys() & b.keys() # {'y'} — umumiy kalitlar
a.keys() - b.keys() # {'x'}Saralash#
dict(sorted(narxlar.items())) # kalit bo'yicha
dict(sorted(narxlar.items(), key=lambda kv: kv[1], reverse=True)) # qiymat bo'yicha, kamayish
max(narxlar, key=narxlar.get) # 'uzum' — eng qimmatining kaliti5. Birlashtirish va yangilash#
default = {"model": "claude-opus-5-5", "max_tokens": 1024, "effort": "medium"}
user = {"max_tokens": 4096}
# 1. Yangi lug'at — o'ngdagisi ustun
params = {**default, **user} # Python 3.5+
params = default | user # Python 3.9+ — eng o'qiladigan
# 2. Joyida yangilash
default.update(user) # default o'zgaradi
default |= user # xuddi shundayNatija: {'model': 'claude-opus-5-5', 'max_tokens': 4096, 'effort': 'medium'}.
Bu naqsh — "standart sozlamalar + foydalanuvchi sozlamalari" — har bir
loyihada uchraydi.
6. To'plam (set)#
To'plam — takrorlanmaydigan, tartibsiz, hashlanadigan elementlar to'plami. Ichkarida — kalitlari bor, qiymatlari yo'q lug'at.
s = {1, 2, 3}
s.add(4)
s.discard(10) # yo'q bo'lsa — jim (remove esa KeyError beradi)
bo_sh = set() # {} — bu bo'sh LUG'AT, to'plam emas!
set([3, 1, 3, 2]) # {1, 2, 3} — dublikatlar yo'qoladiMatematik amallar#
a = {1, 2, 3}
b = {2, 3, 4}
a | b # {1, 2, 3, 4} — birlashma (union)
a & b # {2, 3} — kesishma (intersection)
a - b # {1} — ayirma (difference)
a ^ b # {1, 4} — simmetrik ayirma
{1, 2} <= a # True — qism to'plammi (subset)Qachon to'plam ishlatish kerak#
1. Tez a'zolikni tekshirish. Bu eng muhim qo'llanish:
stop_words = {"va", "bilan", "uchun", "ham", "bu", "u"} # set!
def filter_tokens(tokens: list[str]) -> list[str]:
return [t for t in tokens if t not in stop_words] # har tekshiruv O(1)Agar stop_words ro'yxat bo'lsa va 500 so'zdan iborat bo'lsa, million
tokenli matnda 500 million taqqoslash bo'ladi. To'plam bilan — million.
2. Dublikatlarni olib tashlash. set(lst) — lekin tartib yo'qoladi.
Tartib kerak bo'lsa: list(dict.fromkeys(lst)).
3. Ikki to'plamni solishtirish. Masalan, train va test'da umumiy foydalanuvchilar bormi (ma'lumot sizib chiqishi — data leakage!):
train_users = set(train_df["user_id"])
test_users = set(test_df["user_id"])
umumiy = train_users & test_users
if umumiy:
print(f"⚠️ {len(umumiy)} ta foydalanuvchi ikkala qismda ham bor!")frozenset#
O'zgarmas to'plam — hashlanadi, shuning uchun lug'at kaliti yoki boshqa
to'plam elementi bo'la oladi: {frozenset({"a", "b"}): 1}.
7. collections moduli — maxsus tuzilmalar#
Standart kutubxonadagi bu modul har kuni kerak bo'ladigan tayyor tuzilmalarni beradi.
Counter — sanash#
from collections import Counter
so_zlar = "the cat and the hat and the bat".split()
c = Counter(so_zlar)
c # Counter({'the': 3, 'and': 2, 'cat': 1, 'hat': 1, 'bat': 1})
c["the"] # 3
c["yo'q"] # 0 — KeyError emas!
c.most_common(2) # [('the', 3), ('and', 2)]
c.total() # 8 (Python 3.10+)
c.update(["the", "dog"]) # qo'shimcha sanash
Counter("abracadabra").most_common(2) # [('a', 5), ('b', 2)]ML'da: sinflar balansini tekshirish — Counter(labels). Agar
Counter({0: 9500, 1: 500}) chiqsa — ma'lumotlar nomutanosib (imbalanced),
accuracy chalg'ituvchi metrika bo'ladi.
defaultdict — standart qiymatli lug'at#
from collections import defaultdict
# Guruhlash: har bir harf bilan boshlanadigan so'zlar
guruhlar = defaultdict(list)
for soz in ["olma", "anor", "nok", "orik", "nar"]:
guruhlar[soz[0]].append(soz) # kalit yo'q bo'lsa — avtomatik [] yaratiladi
dict(guruhlar) # {'o': ['olma', 'orik'], 'a': ['anor'], 'n': ['nok', 'nar']}defaultdict(int) — sanash uchun, defaultdict(list) — guruhlash uchun,
defaultdict(set) — unikal guruhlash uchun.
deque — ikki tomonli navbat#
from collections import deque
q = deque([1, 2, 3])
q.append(4) # o'ngga — O(1)
q.appendleft(0) # chapga — O(1) (list.insert(0, x) — O(n))
q.popleft() # chapdan olish — O(1) (list.pop(0) — O(n))
oxirgilar = deque(maxlen=3) # faqat oxirgi 3 ta element saqlanadi
for i in range(5):
oxirgilar.append(i)
print(oxirgilar) # deque([2, 3, 4], maxlen=3)deque(maxlen=N) — "oxirgi N ta" uchun ideal: chat'ning oxirgi N xabari,
oxirgi 100 ta loss qiymatining o'rtachasi, reinforcement learning'dagi
replay buffer.
namedtuple — nomlangan maydonli tuple#
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
p.x, p.y # (3, 4) — nom bilan
p[0] # 3 — indeks bilan ham
x, y = p # unpacking ham ishlaydi
p._replace(x=10) # Point(x=10, y=4) — yangi obyekt
p._asdict() # {'x': 3, 'y': 4}Zamonaviy kodda ko'proq typing.NamedTuple yoki dataclass (13-bob)
ishlatiladi — ular type hint'lar bilan yaxshiroq ishlaydi.
ChainMap — bir nechta lug'atni qatlam qilib ko'rish#
from collections import ChainMap
cli_args = {"lr": 0.1}
env = {"epochs": 20}
defaults = {"lr": 0.01, "epochs": 10, "batch_size": 32}
cfg = ChainMap(cli_args, env, defaults) # chapdagisi ustun
cfg["lr"], cfg["epochs"], cfg["batch_size"] # (0.1, 20, 32)8. Qaysi tuzilmani tanlash kerak?#
| Vazifa | Tuzilma | Nega |
|---|---|---|
| Tartiblangan elementlar, indeks bo'yicha kirish | list | O(1) indeks |
| O'zgarmas yozuv, funksiyadan bir nechta qiymat | tuple | Ma'no + hashlanadi |
| Kalit bo'yicha qidirish | dict | O(1) |
| "Bormi?" tekshiruvi, dublikatlarni olib tashlash | set | O(1) in |
| Sanash | Counter | Tayyor most_common |
| Guruhlash | defaultdict(list) | Tekshiruvsiz append |
| Navbat, oxirgi N ta | deque | O(1) ikki tomonda |
| Raqamlar massivi, matematik amallar | numpy.ndarray | Vektorlashtirish (19-bob) |
| Jadval ma'lumotlari | pandas.DataFrame | Ustunlar, guruhlash, birlashtirish (20-bob) |
9. Amaliyot: so'z chastotasi va oddiy "vocabulary"#
NLP'ning birinchi qadami — matndan lug'at (vocabulary) qurish: har bir so'zga raqam berish. Tokenizer'lar aynan shunday boshlanadi:
from collections import Counter
corpus = [
"Python ML uchun eng mashhur til",
"ML modellar ma'lumotdan o'rganadi",
"Python va ML birga",
]
# 1. So'zlarni sanash
counts = Counter(word for line in corpus for word in line.lower().split())
# 2. Kamida 2 marta uchragan so'zlardan lug'at
SPECIAL = ["<pad>", "<unk>"]
vocab = SPECIAL + [w for w, n in counts.most_common() if n >= 2]
word2id = {w: i for i, w in enumerate(vocab)}
id2word = {i: w for w, i in word2id.items()}
def encode(text: str) -> list[int]:
unk = word2id["<unk>"]
return [word2id.get(w, unk) for w in text.lower().split()]
def decode(ids: list[int]) -> str:
return " ".join(id2word[i] for i in ids)
print(word2id) # {'<pad>': 0, '<unk>': 1, 'ml': 2, 'python': 3}
print(encode("Python ML zo'r")) # [3, 2, 1]
print(decode([3, 2, 1])) # python ml <unk>Bu yerda deyarli bobning hamma narsasi bor: Counter sanash uchun,
most_common saralash uchun, dict comprehension ikki tomonlama lug'at
uchun, get(w, unk) noma'lum so'zlar uchun. Haqiqiy tokenizer'lar
(BPE, SentencePiece) murakkabroq, lekin g'oya aynan shu.
Nima noto'g'ri ketishi mumkin#
| Holat | Natija | To'g'risi |
|---|---|---|
d["yo'q_kalit"] | KeyError | d.get(k, default) |
{} bo'sh to'plam deb | Bo'sh lug'at | set() |
| Ro'yxatni kalit qilish | TypeError: unhashable type | tuple(lst) |
dict.fromkeys(k, []) | Hamma kalit bitta ro'yxatda | {x: [] for x in k} |
| Aylanish paytida kalit qo'shish/o'chirish | RuntimeError | for k in list(d): |
defaultdictda if d[k]: | Kalit yaratiladi | if k in d: |
Ichma-ich lug'atlarni | bilan birlashtirish | Ichki lug'at to'liq almashadi | Rekursiv merge |
set(lst) tartibni saqlaydi deb | Tartib yo'qoladi | list(dict.fromkeys(lst)) |
Katta ro'yxatda in | O(n) — sekin | set |
1, 1.0, True turli kalit deb | Bitta kalitga birlashadi | Kalit tiplarini aralashtirmang |
1. Inverted index
Qidiruv tizimlarining asosi — inverted index. Hujjatlar ro'yxatidan
{so'z: {hujjat_id, ...}} lug'atini quring, keyin search("python ml")
funksiyasi ikkala so'z ham uchragan hujjatlar id'larini qaytarsin.
Maslahatni ko'rsatish
defaultdict(set): for doc_id, text in enumerate(docs): for w in text.lower().split(): index[w].add(doc_id). AND qidiruv — to'plamlar kesishmasi.
2. Sinflar balansi
labels = ["spam"] * 120 + ["ham"] * 880 berilgan. Har bir sinf ulushini
foizda chiqaring va "class weight"larni hisoblang: w_c = N / (K * n_c)
(N — jami, K — sinflar soni, n_c — sinfdagi namunalar). Bu og'irliklar
nomutanosib ma'lumotda model o'qitishda ishlatiladi.
Maslahatni ko'rsatish
Counter(labels), keyin har bir sinf uchun n / total. Og'irlik: total / (n_classes * n).
3. Chuqur birlashtirish
deep_merge(a, b) funksiyasini yozing: ichma-ich lug'atlarni rekursiv
birlashtirsin. deep_merge({"opt": {"lr": 1, "wd": 0}, "ep": 5}, {"opt": {"lr": 2}})
→ {"opt": {"lr": 2, "wd": 0}, "ep": 5}.
Maslahatni ko'rsatish
Agar ikkala qiymat ham dict bo'lsa — rekursiv chaqiring, aks holda o'ngdagisini oling. Asl lug'atlarni o'zgartirmang.
4. LRU kesh qo'lda
Oxirgi n ta ishlatilgan kalitni saqlaydigan kesh yozing: get(k) va
put(k, v) metodlari bilan; joy tugaganda eng uzoq ishlatilmagan element
o'chirilsin. Maslahat: oddiy dict tartibni saqlaydi — getda kalitni
pop qilib qayta qo'shsangiz, u "eng yangi" bo'ladi; eng eskisi —
next(iter(d)). (8-bobda tayyor functools.lru_cacheni ko'ramiz.)
- 01dict — hash jadval: qidirish, qo'shish, o'chirish o'rtacha O(1); 3.7+ da tartib saqlanadi.
- 02Kalit hashlanadigan (immutable) bo'lishi kerak: str, int, tuple — ha; list, dict, set — yo'q.
- 03get(k, default), setdefault, pop(k, None) — KeyError'siz ishlash.
- 04default | user — sozlamalarni birlashtirish naqshi (sayoz!).
- 05set — O(1) a'zolik tekshiruvi va to'plam amallari; {} — bo'sh lug'at, set() — bo'sh to'plam.
- 06Counter — sanash, defaultdict — guruhlash, deque — navbat va oxirgi N ta, namedtuple — nomli yozuv.
- 07Vazifaga mos tuzilma tanlash — performansning eng arzon usuli.
Mustahkamlash
Test va amaliy masalalar
Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.
Bilimni tekshirish
Bob bo'yicha test
12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.
Amaliy masalalar
Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.
01So'z chastotasi
top_words(text, n) — matnni kichik harfga o'tkazib, bo'sh joylar bo'yicha bo'lib, eng ko'p uchragan n ta so'zni [(so'z, soni), ...] ko'rinishida qaytarsin (collections.Counter).
02Inverted index
build_index(docs) — {so'z: {hujjat_indekslari}} lug'atini qursin (kichik harf, split()). search(index, query) — so'rovdagi barcha so'zlar uchragan hujjatlar indekslarini saralangan ro'yxat qilib qaytarsin.
03Chuqur birlashtirish
deep_merge(a, b) — ichma-ich lug'atlarni rekursiv birlashtirsin (b ustun), asl lug'atlar o'zgarmasin. deep_merge({"opt": {"lr": 1, "wd": 0}, "ep": 5}, {"opt": {"lr": 2}}) → {"opt": {"lr": 2, "wd": 0}, "ep": 5}.