Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Barcha metodlar
- 2.2. get vs setdefault vs pop
- 2.3. update — barcha shakllar
- 2.4. collections.defaultdict
- 2.5. collections.Counter
- 2.6. ChainMap va OrderedDict
- 2.7. Tezlik solishtirilishi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Metodlar to'liq
- Misol 2 — defaultdict
- Misol 3 — Counter, ChainMap, OrderedDict
- Misol 4 — Amaliy: log tahlilchisi
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
6.11-dars: dict metodlari
6-QISM — MA'LUMOT TUZILMALARI · 11-dars
1. Kirish va motivatsiya
dict da 11 ta metod bor — list bilan bir xil son. Lekin ularning nozikliklari ko'proq:
d.get(k) # None qaytaradi
d.get(k, sukut) # sukut qaytaradi
d.setdefault(k, sukut) # sukut qaytaradi VA QO'SHADI
d.pop(k, sukut) # o'chirib qaytaradiUchtasi "sukut qiymat" bilan ishlaydi, lekin uchalasi turlicha xatti-harakat qiladi. Qaysi birini qachon?
Va amaliy savol: sanash vazifasi. To'rt xil yozish mumkin:
# 1
hisob = {}
for x in malumot:
if x in hisob:
hisob[x] += 1
else:
hisob[x] = 1
# 2
hisob = {}
for x in malumot:
hisob[x] = hisob.get(x, 0) + 1
# 3
from collections import defaultdict
hisob = defaultdict(int)
for x in malumot:
hisob[x] += 1
# 4
from collections import Counter
hisob = Counter(malumot)Qaysi biri eng yaxshi? Nega?
Bu darsda:
- Barcha 11 metod va murakkabligi
getvssetdefaultvspop— aniq farqlarupdatening barcha shakllaricollections:defaultdict,Counter,ChainMap,OrderedDict- Sanash, guruhlash, invertlash naqshlari
- Tezlik solishtirilishi
2. Nazariya — chuqur tushuntirish
2.1. Barcha metodlar
d = {"a": 1}
print([m for m in dir(d) if not m.startswith("_")])['clear', 'copy', 'fromkeys', 'get', 'items', 'keys',
'pop', 'popitem', 'setdefault', 'update', 'values']| Metod | Nima qiladi | Qaytaradi | Murakkablik |
|---|---|---|---|
get(k, s=None) |
Xavfsiz o'qish | Qiymat yoki s |
O(1) |
setdefault(k, s=None) |
O'qish + qo'shish | Qiymat yoki s |
O(1) |
pop(k[, s]) |
O'chirib qaytarish | Qiymat | O(1) |
popitem() |
Oxirgi juftlikni | (k, v) |
O(1) |
update(...) |
Birlashtirish | None |
O(k) |
clear() |
Tozalash | None |
O(1) |
copy() |
Sayoz nusxa | Yangi dict |
O(n) |
keys() |
Kalitlar ko'rinishi | View | O(1) |
values() |
Qiymatlar ko'rinishi | View | O(1) |
items() |
Juftliklar ko'rinishi | View | O(1) |
fromkeys(k, v) |
Sinf metodi | Yangi dict |
O(n) |
clear() — O(1), list.clear() esa O(n). Lug'at butun jadvalni bir marta bo'shatadi.
2.2. get vs setdefault vs pop
Uchalasi ham "sukut qiymat" bilan ishlaydi, lekin farqli:
d = {"a": 1}
d.get("b", 0) # 0 — d o'zgarmaydi
print(d) # {'a': 1}
d.setdefault("b", 0) # 0 — d GA QO'SHILDI
print(d) # {'a': 1, 'b': 0}
d.pop("b", 0) # 0 — d dan O'CHIRILDI
print(d) # {'a': 1}Jadval:
| Kalit bor | Kalit yo'q | d o'zgaradi |
|
|---|---|---|---|
get(k, s) |
Qiymat | s |
|
setdefault(k, s) |
Qiymat | s |
qo'shadi |
pop(k, s) |
Qiymat | s |
o'chiradi |
pop(k) |
Qiymat | KeyError |
|
d[k] |
Qiymat | KeyError |
setdefault nomi chalkash. U "sukut qiymatni o'rnatish" emas, "yo'q bo'lsa qo'yish va qaytarish". Aniqroq nom get_or_set bo'lardi.
Sukut qiymat DOIM hisoblanadi:
d.setdefault(k, qimmat_funksiya()) # ⚠️ kalit bor bo'lsa ham chaqiriladi
d.get(k, qimmat_funksiya()) # ⚠️ ham chaqiriladi
d.pop(k, qimmat_funksiya()) # ⚠️ hamBu — Python semantikasi: argumentlar funksiya chaqirilishidan oldin hisoblanadi. Dangasa hisoblash uchun:
if k not in d:
d[k] = qimmat_funksiya() # ✅ faqat kerak bo'lgandasetdefault ning klassik qo'llanishi — guruhlash:
guruhlar = {}
for soz in sozlar:
guruhlar.setdefault(soz[0], []).append(soz)Lekin defaultdict yaxshiroq (2.4-bo'lim).
2.3. update — barcha shakllar
d.update(boshqa_lugat)
d.update([("a", 1), ("b", 2)]) # juftliklar
d.update(zip("ab", [1, 2])) # zip
d.update(a=1, b=2) # nomli argumentlar
d.update({"a": 1}, b=2) # aralash
d.update() # hech narsaNomli argumentlar oxirida va kalitlar identifikator bo'lishi kerak:
d.update(a=1) # ✅
d.update(**{"1-kalit": 1}) # ⚠️ ishlaydi
d.update({"1-kalit": 1}) # ✅ toza usul update None qaytaradi:
d = d.update({"a": 1}) # ❌ d endi None!
d.update({"a": 1}) # ✅
yangi = d | {"a": 1} # ✅ yangi lug'atChuqur birlashtirish emas:
d1 = {"a": {"x": 1, "y": 2}}
d2 = {"a": {"x": 99}}
d1.update(d2)
print(d1) # {'a': {'x': 99}} ← 'y' YO'QOLDIupdate — sayoz. Ichma-ich lug'atlar to'liq almashtiriladi. Chuqur birlashtirish uchun rekursiv funksiya kerak (4-misolda).
2.4. collections.defaultdict
defaultdict — yo'q kalitga murojaat qilganda avtomatik sukut qiymat yaratadi.
from collections import defaultdict
d = defaultdict(list)
d["a"].append(1) # 'a' yo'q edi — [] yaratildi
print(d) # defaultdict(<class 'list'>, {'a': [1]})Konstruktor argumenti — CHAQIRILADIGAN (callable):
defaultdict(list) # []
defaultdict(int) # 0
defaultdict(set) # set()
defaultdict(dict) # {}
defaultdict(str) # ""
defaultdict(lambda: "yo'q") # "yo'q"
defaultdict(lambda: [0] * 3) # [0, 0, 0]Chaqiriladigan, qiymat emas:
defaultdict(0) # ❌ TypeError: first argument must be callable
defaultdict(int) # ✅ int() → 0
defaultdict(lambda: 0) # ✅Murojaat ham kalit YARATADI:
d = defaultdict(int)
print(d["yo'q"]) # 0
print(d) # {"yo'q": 0} ← QO'SHILDI!
print(len(d)) # 1Bu — eng ko'p uchraydigan tuzoq. Tekshirish uchun:
if k in d: # ✅ kalit yaratmaydi
d.get(k) # ✅ kalit yaratmaydi
d[k] # ⚠️ YARATADI__missing__ — ichki mexanizm:
class Mening(dict):
def __missing__(self, kalit):
qiymat = f"sukut-{kalit}"
self[kalit] = qiymat # ixtiyoriy — saqlash
return qiymat
d = Mening()
print(d["x"]) # sukut-xdefaultdict aynan shunday ishlaydi. __missing__ faqat d[k] uchun chaqiriladi — get uchun emas.
default_factory ni o'zgartirish:
d = defaultdict(list)
d.default_factory = None # endi oddiy dict kabi
d["yo'q"] # ❌ KeyErrordefaultdict vs setdefault vs get:
# Sanash
hisob = defaultdict(int)
for x in m: hisob[x] += 1 # ✅ eng tez
hisob = {}
for x in m: hisob[x] = hisob.get(x, 0) + 1 # ✅ oddiy dict
# Guruhlash
guruh = defaultdict(list)
for x in m: guruh[kalit(x)].append(x) # ✅ eng tez
guruh = {}
for x in m: guruh.setdefault(kalit(x), []).append(x)2.5. collections.Counter
Counter — sanash uchun maxsus lug'at (defaultdict(int) ning kengaytmasi).
from collections import Counter
c = Counter("mississippi")
# Counter({'i': 4, 's': 4, 'p': 2, 'm': 1})
c = Counter([1, 1, 2, 3]) # ro'yxatdan
c = Counter({"a": 3, "b": 1}) # lug'atdan
c = Counter(a=3, b=1) # nomli argumentMetodlar:
c.most_common() # [('i',4), ('s',4), ('p',2), ('m',1)]
c.most_common(2) # eng ko'p 2 tasi
c.total() # 11 — barcha sanoqlar (3.10+)
c.elements() # iterator: i,i,i,i,s,s,s,s,p,p,m
c.subtract(boshqa) # ayirish (manfiy bo'lishi mumkin)
c.update(boshqa) # qo'shish Yo'q kalit — KeyError emas, 0:
c = Counter("abc")
c["z"] # 0 — xato yo'q
print(c) # Counter({'a':1,'b':1,'c':1}) ← qo'shilmadi! defaultdict dan farq: Counter yo'q kalitni qo'shmaydi.
Arifmetik amallar:
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2, c=1)
c1 + c2 # Counter({'a':4, 'b':3, 'c':1})
c1 - c2 # Counter({'a':2}) ← manfiylar tushib qoladi
c1 & c2 # Counter({'a':1, 'b':1}) — min
c1 | c2 # Counter({'a':3, 'b':2, 'c':1}) — max - manfiy va nol sanoqlarni olib tashlaydi:
Counter(a=1) - Counter(a=3) # Counter() ← bo'sh
Counter(a=1).subtract(Counter(a=3)) # Counter({'a': -2}) ← saqlanadiAmaliy misollar:
# Eng ko'p uchraydigan so'zlar
Counter(matn.split()).most_common(10)
# Ikki matn o'xshashligi
umumiy = Counter(a) & Counter(b)
oxshashlik = sum(umumiy.values()) / max(len(a), len(b))
# Anagram tekshiruvi
Counter("listen") == Counter("silent") # True
# Takrorlarni topish
{x for x, n in Counter(r).items() if n > 1}2.6. ChainMap va OrderedDict
ChainMap — bir nechta lug'atni birlashtirmasdan ko'rish:
from collections import ChainMap
standart = {"til": "uz", "tema": "yorug'"}
foydalanuvchi = {"tema": "qorong'i"}
sozlamalar = ChainMap(foydalanuvchi, standart)
sozlamalar["tema"] # "qorong'i" ← birinchi topilgani
sozlamalar["til"] # "uz"Nusxa yaratmaydi — qidiruv zanjir bo'ylab ketadi.
foydalanuvchi["til"] = "en"
sozlamalar["til"] # "en" ← avtomatik yangilandiYozish — faqat birinchi lug'atga:
sozlamalar["yangi"] = 1
print(foydalanuvchi) # {'tema': "qorong'i", 'yangi': 1}
print(standart) # o'zgarmadiQachon foydali:
- Konfiguratsiya qatlamlari (CLI → muhit → fayl → standart)
- Vaqtinchalik o'zgarishlar (
new_child()) - Nom fazolari (Python o'zi
locals→globals→builtinsuchun ishlatadi)
vaqtinchalik = sozlamalar.new_child({"debug": True})
# Asl zanjir o'zgarmaydiOrderedDict — 3.7 dan keyin ham foydali:
from collections import OrderedDict
od = OrderedDict([("a", 1), ("b", 2)])dict tartibni saqlagach, OrderedDict deyarli keraksiz. Lekin uch farq qoldi:
1. Tenglikda tartib muhim:
OrderedDict(a=1, b=2) == OrderedDict(b=2, a=1) # False
dict(a=1, b=2) == dict(b=2, a=1) # True2. move_to_end:
od.move_to_end("a") # oxirga
od.move_to_end("a", last=False) # boshiga3. popitem(last=False) — FIFO:
od.popitem() # oxirgisi (LIFO)
od.popitem(last=False) # birinchisi (FIFO)
d.popitem() # faqat LIFOShuning uchun LRU kesh yozishda OrderedDict hali ham qulay.
2.7. Tezlik solishtirilishi
Sanash vazifasi uchun (100k element):
| Usul | Nisbiy tezlik |
|---|---|
Counter(malumot) |
1.0x (C da) |
defaultdict(int) |
~2.5x |
d.get(x, 0) + 1 |
~3.2x |
if x in d: ... else: ... |
~3.0x |
d.setdefault(x, 0) |
~4.5x |
try/except KeyError |
~3.5x (xatolar kam bo'lsa tezroq) |
Counter(iterable) — C darajasida optimallashtirilgan (_count_elements).
Lekin Counter ni siklda yangilash sekin:
c = Counter()
for x in m:
c[x] += 1 # ⚠️ defaultdict dan sekinroq
c = Counter(m) # ✅ eng tezUmumiy tavsiya:
Sanash: Counter(iterable)
Guruhlash: defaultdict(list)
Qatlamlar: ChainMap
Bir marta o'qish: d.get(k, sukut)
LRU/FIFO: OrderedDict
Oddiy holat: oddiy dict3. Tez ma'lumotnoma
11 metod
get(k, s) o'qish, d o'zgarmaydi
setdefault(k, s) o'qish + QO'SHADI ⭐
pop(k[, s]) o'chirib qaytaradi
popitem() oxirgi juftlik (LIFO, 3.7+)
update(...) birlashtirish, None qaytaradi
clear() O(1) ⭐ (list.clear O(n))
copy() sayoz
keys/values/items ko'rinishlar
fromkeys(k, v) sinf metodiSukut qiymat DOIM hisoblanadi
d.setdefault(k, qimmat()) ⚠️ kalit bor bo'lsa ham
if k not in d: d[k] = qimmat() ✅collections
defaultdict(list) d[k].append(x) ⚠️ murojaat KALIT YARATADI
defaultdict(int) d[k] += 1
Counter(iterable) ⭐ eng tez sanash
most_common(n), total(), elements()
+ - & | (- manfiylarni tushiradi)
c["yo'q"] → 0, kalit QO'SHILMAYDI
ChainMap(d1, d2) nusxasiz qatlamlar, yozish → d1
OrderedDict tenglikda tartib, move_to_end,
popitem(last=False) — FIFONaqshlar
Sanash: Counter(m)
Guruhlash: defaultdict(list); d[kalit(x)].append(x)
Invertlash: {v: k for k, v in d.items()}
Filtrlash: {k: v for k, v in d.items() if shart}
Birlashtirish: d1 | d2
Qatlamlar: ChainMap(cli, muhit, fayl, standart)4. Batafsil misollar
Misol 1 — Metodlar to'liq
"""Barcha dict metodlari va ularning nozikliklari."""
print("=== 1. ⭐ get vs setdefault vs pop ===")
BOSHLANGICH = {"a": 1, "b": 2}
AMALLAR = [
('d.get("a")', lambda d: d.get("a")),
('d.get("z")', lambda d: d.get("z")),
('d.get("z", 0)', lambda d: d.get("z", 0)),
('d.setdefault("a", 99)', lambda d: d.setdefault("a", 99)),
('d.setdefault("z", 0)', lambda d: d.setdefault("z", 0)),
('d.pop("a")', lambda d: d.pop("a")),
('d.pop("z", 0)', lambda d: d.pop("z", 0)),
('d.popitem()', lambda d: d.popitem()),
]
print(f" Boshlang'ich: {BOSHLANGICH}\n")
print(f" {'Amal':<26} {'Qaytardi':<14} {'d keyin'}")
print(" " + "─" * 60)
for kod, f in AMALLAR:
d = BOSHLANGICH.copy()
try:
natija = repr(f(d))
except KeyError as x:
natija = f"❌ KeyError"
print(f" {kod:<26} {natija:<14} {d}")
try:
BOSHLANGICH.copy().pop("z")
except KeyError as x:
print(f" {'d.pop(\"z\")':<26} ❌ KeyError: {x}")
print("""
⭐ get — o'qiydi, d O'ZGARMAYDI
setdefault — o'qiydi, yo'q bo'lsa QO'SHADI
pop — o'qiydi va O'CHIRADI
""")
print("\n=== 2. ⚠️ Sukut qiymat doim hisoblanadi ===")
chaqiruvlar = []
def qimmat(nom="?"):
chaqiruvlar.append(nom)
return f"hisoblandi-{nom}"
d = {"a": 1}
chaqiruvlar.clear()
d.get("a", qimmat("get"))
d.setdefault("a", qimmat("setdefault"))
d.pop("a", qimmat("pop"))
print(f" Kalit 'a' BOR, lekin funksiya chaqirildi: {chaqiruvlar}")
print("\n ✅ Dangasa hisoblash:")
d = {"a": 1}
chaqiruvlar.clear()
if "a" not in d:
d["a"] = qimmat("if")
print(f" if k not in d: ... → chaqiruvlar: {chaqiruvlar or 'yo`q'}")
print("""
Sabab: Pythonda argumentlar funksiya chaqirilishidan
OLDIN hisoblanadi (eager evaluation).
""")
print("\n=== 3. update — barcha shakllar ===")
SHAKLLAR = [
('d.update({"x": 1})', lambda d: d.update({"x": 1})),
('d.update([("x", 1)])', lambda d: d.update([("x", 1)])),
('d.update(zip("xy", [1, 2]))', lambda d: d.update(zip("xy", [1, 2]))),
('d.update(x=1, y=2)', lambda d: d.update(x=1, y=2)),
('d.update({"x": 1}, y=2)', lambda d: d.update({"x": 1}, y=2)),
('d.update()', lambda d: d.update()),
]
print(f" Boshlang'ich: {{'a': 0}}\n")
for kod, f in SHAKLLAR:
d = {"a": 0}
natija = f(d)
print(f" {kod:<34} → {d} (qaytardi: {natija})")
print(f"\n ⚠️ update None qaytaradi:")
d = {"a": 1}
natija = d.update({"b": 2})
print(f" d = d.update({{'b': 2}}) → d = {natija} ❌")
print(f" d.update({{'b': 2}}) → ✅")
print(f" yangi = d | {{'b': 2}} → ✅")
print(f"\n ⚠️ Sayoz birlashtirish:")
d1 = {"a": {"x": 1, "y": 2}, "b": 1}
d2 = {"a": {"x": 99}}
nusxa = {k: (v.copy() if isinstance(v, dict) else v) for k, v in d1.items()}
nusxa.update(d2)
print(f" d1 = {d1}")
print(f" d2 = {d2}")
print(f" update → {nusxa}")
print(f" ⚠️ 'y' YO'QOLDI — ichki lug'at to'liq almashtirildi")
print("\n=== 4. Chuqur birlashtirish ===")
def chuqur_birlashtir(a: dict, b: dict) -> dict:
"""Ichma-ich lug'atlarni rekursiv birlashtiradi."""
natija = dict(a)
for kalit, qiymat in b.items():
if (kalit in natija
and isinstance(natija[kalit], dict)
and isinstance(qiymat, dict)):
natija[kalit] = chuqur_birlashtir(natija[kalit], qiymat)
else:
natija[kalit] = qiymat
return natija
D1 = {
"baza": {"host": "localhost", "port": 5432, "ssl": False},
"kesh": {"turi": "redis", "ttl": 300},
"debug": False,
}
D2 = {
"baza": {"host": "db.wisar.uz", "ssl": True},
"kesh": {"ttl": 600},
"log": "DEBUG",
}
print(f" D1: {D1}")
print(f" D2: {D2}\n")
sayoz = D1 | D2
print(f" Sayoz (D1 | D2):")
for k, v in sayoz.items():
print(f" {k}: {v}")
chuqur = chuqur_birlashtir(D1, D2)
print(f"\n Chuqur:")
for k, v in chuqur.items():
print(f" {k}: {v}")
print(f"\n ⭐ Chuqur birlashtirish 'port' va 'turi' ni SAQLADI")
print("\n=== 5. popitem va clear ===")
d = {"a": 1, "b": 2, "c": 3}
print(f" d = {d}\n")
nusxa = d.copy()
print(f" popitem() ketma-ket (LIFO):")
while nusxa:
print(f" {nusxa.popitem()} qoldi: {nusxa}")
print(f"\n ⭐ Oxirgi qo'shilgandan boshlab (3.7+)")
import time
KATTA = dict.fromkeys(range(500_000))
boshlandi = time.perf_counter()
KATTA.clear()
vaqt_dict = time.perf_counter() - boshlandi
KATTA_LIST = list(range(500_000))
boshlandi = time.perf_counter()
KATTA_LIST.clear()
vaqt_list = time.perf_counter() - boshlandi
print(f"\n clear() tezligi (500k element):")
print(f" dict.clear(): {vaqt_dict * 1000:>8.3f} ms O(1)")
print(f" list.clear(): {vaqt_list * 1000:>8.3f} ms O(n)")
print("\n=== 6. Ko'rinishlar bilan ishlash ===")
D = {"a": 1, "b": 2, "c": 3}
print(f" d = {D}\n")
AMALLAR = [
("len(d.keys())", len(D.keys())),
("'a' in d.keys()", "a" in D.keys()),
("1 in d.values()", 1 in D.values()),
("('a', 1) in d.items()", ("a", 1) in D.items()),
("list(d.items())", list(D.items())),
("sorted(d.items(), key=lambda x: -x[1])",
sorted(D.items(), key=lambda x: -x[1])),
("dict(reversed(d.items()))", dict(reversed(D.items()))),
("max(d, key=d.get)", max(D, key=D.get)),
("min(d.values())", min(D.values())),
("sum(d.values())", sum(D.values())),
]
for kod, natija in AMALLAR:
print(f" {kod:<40} → {natija}")
print(f"\n ⚠️ 1 in d — KALITLAR bo'yicha qidiradi:")
print(f" 1 in {{'a': 1}} → {1 in {'a': 1}}")
print(f" 1 in {{'a': 1}}.values() → {1 in {'a': 1}.values()}")Natijaning muhim qismi:
=== 1. ⭐ get vs setdefault vs pop ===
Amal Qaytardi d keyin
────────────────────────────────────────────────────────────
d.get("a") 1 {'a': 1, 'b': 2}
d.get("z") None {'a': 1, 'b': 2}
d.setdefault("a", 99) 1 {'a': 1, 'b': 2}
d.setdefault("z", 0) 0 {'a': 1, 'b': 2, 'z': 0}
d.pop("a") 1 {'b': 2}
d.popitem() ('b', 2) {'a': 1}
=== 2. ⚠️ Sukut qiymat doim hisoblanadi ===
Kalit 'a' BOR, lekin funksiya chaqirildi: ['get', 'setdefault', 'pop']
=== 5. popitem va clear ===
clear() tezligi (500k element):
dict.clear(): 0.184 ms O(1)
list.clear(): 2.412 ms O(n)Nima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.
Misol 2 — defaultdict
"""defaultdict — avtomatik sukut qiymatlar."""
from collections import defaultdict
print("=== 1. Asosiy shakllar ===")
SHAKLLAR = [
("defaultdict(list)", defaultdict(list), "append"),
("defaultdict(int)", defaultdict(int), "+="),
("defaultdict(set)", defaultdict(set), "add"),
("defaultdict(dict)", defaultdict(dict), "ichki"),
("defaultdict(str)", defaultdict(str), "+="),
("defaultdict(lambda: 'yo`q')", defaultdict(lambda: "yo'q"), "sukut"),
("defaultdict(lambda: [0]*3)", defaultdict(lambda: [0] * 3), "vektor"),
]
print(f" {'Shakl':<30} {'d[k] boshlang`ich qiymati'}")
print(" " + "─" * 60)
for nom, d, _ in SHAKLLAR:
print(f" {nom:<30} {d['yangi_kalit']!r}")
print(f"\n ⚠️ Konstruktor CHAQIRILADIGAN bo'lishi kerak:")
try:
defaultdict(0)
except TypeError as x:
print(f" defaultdict(0) → ❌ {x}")
print(f" defaultdict(int) → ✅ int() = {int()}")
print(f" defaultdict(lambda: 0) → ✅")
print("\n=== 2. ⚠️ Murojaat kalit YARATADI ===")
d = defaultdict(int)
print(f" d = defaultdict(int)")
print(f" len(d) = {len(d)}")
qiymat = d["yo'q"]
print(f"\n d['yo`q'] o'qildi → {qiymat}")
print(f" len(d) = {len(d)} ⚠️ KALIT QO'SHILDI!")
print(f" d = {dict(d)}")
print(f"\n ✅ Kalit yaratmaydigan usullar:")
d2 = defaultdict(int)
print(f" 'x' in d2 → {'x' in d2}, len = {len(d2)}")
print(f" d2.get('x') → {d2.get('x')}, len = {len(d2)}")
print(f" d2.get('x', 0) → {d2.get('x', 0)}, len = {len(d2)}")
print("""
⭐ Bu — defaultdict ning eng ko'p uchraydigan tuzog'i.
Tekshirish uchun `in` yoki `get` ishlating.
""")
print("\n=== 3. Guruhlash naqshlari ===")
SOZLAR = ["olma", "anor", "behi", "olcha", "uzum", "anjir",
"bodring", "banan", "uzum"]
print(f" So'zlar: {SOZLAR}\n")
# Birinchi harf bo'yicha
harflar = defaultdict(list)
for s in SOZLAR:
harflar[s[0]].append(s)
print(f" Birinchi harf bo'yicha:")
for harf in sorted(harflar):
print(f" {harf}: {harflar[harf]}")
# Uzunlik bo'yicha
uzunliklar = defaultdict(list)
for s in SOZLAR:
uzunliklar[len(s)].append(s)
print(f"\n Uzunlik bo'yicha:")
for n in sorted(uzunliklar):
print(f" {n}: {uzunliklar[n]}")
# Noyob (set bilan)
noyob_harflar = defaultdict(set)
for s in SOZLAR:
noyob_harflar[s[0]].add(s)
print(f"\n Noyob (set bilan):")
for harf in sorted(noyob_harflar):
print(f" {harf}: {sorted(noyob_harflar[harf])}")
# Sanash
hisob = defaultdict(int)
for s in SOZLAR:
hisob[s] += 1
print(f"\n Sanash:")
for s, n in sorted(hisob.items(), key=lambda x: (-x[1], x[0])):
if n > 1:
print(f" {s}: {n} ← takror")
print("\n=== 4. Ichma-ich defaultdict ===")
# Ikki darajali
ikki = defaultdict(lambda: defaultdict(int))
ikki["IT"]["Aziz"] += 100
ikki["IT"]["Bobur"] += 200
ikki["HR"]["Aziza"] += 150
print(f" Ikki darajali:")
for bolim, xodimlar in ikki.items():
print(f" {bolim}:")
for ism, ball in xodimlar.items():
print(f" {ism}: {ball}")
# Cheksiz darajali
def cheksiz():
return defaultdict(cheksiz)
daraxt = cheksiz()
daraxt["a"]["b"]["c"]["d"] = "chuqur qiymat"
print(f"\n Cheksiz daraxt:")
print(f" daraxt['a']['b']['c']['d'] = "
f"{daraxt['a']['b']['c']['d']!r}")
def korsat(d, daraja=0):
for k, v in d.items():
if isinstance(v, dict):
print(f" {' ' * daraja}{k}/")
korsat(v, daraja + 1)
else:
print(f" {' ' * daraja}{k}: {v!r}")
daraxt["a"]["x"] = 1
daraxt["z"]["y"] = 2
print(f"\n Tuzilma:")
korsat(daraxt)
print("\n=== 5. __missing__ — ichki mexanizm ===")
class Kuzatuvchi(dict):
"""defaultdict qanday ishlashini ko'rsatadi."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.yaratilgan = []
def __missing__(self, kalit):
print(f" __missing__({kalit!r}) chaqirildi")
qiymat = f"sukut-{kalit}"
self[kalit] = qiymat
self.yaratilgan.append(kalit)
return qiymat
d = Kuzatuvchi(mavjud="qiymat")
print(f" d = {dict(d)}\n")
print(f" d['mavjud']:")
print(f" → {d['mavjud']!r}")
print(f"\n d['yangi']:")
print(f" → {d['yangi']!r}")
print(f"\n d.get('boshqa'):")
print(f" → {d.get('boshqa')!r} ⭐ __missing__ CHAQIRILMADI")
print(f"\n Yakuniy: {dict(d)}")
print(f" Yaratilgan kalitlar: {d.yaratilgan}")
print("""
⭐ __missing__ FAQAT d[k] uchun chaqiriladi.
get(), in, pop() uchun — yo'q.
defaultdict aynan shu mexanizmni ishlatadi.
""")
print("\n=== 6. default_factory ni o'zgartirish ===")
d = defaultdict(list)
d["a"].append(1)
print(f" d['a'].append(1) → {dict(d)}")
d.default_factory = None
print(f"\n d.default_factory = None")
try:
d["yo'q"]
except KeyError as x:
print(f" d['yo`q'] → ❌ KeyError: {x}")
d.default_factory = int
print(f"\n d.default_factory = int")
print(f" d['yangi'] → {d['yangi']}")
print(f"\n Oddiy dict ga aylantirish:")
print(f" dict(d) → {dict(d)} (turi: {type(dict(d)).__name__})")Natijaning muhim qismi:
=== 2. ⚠️ Murojaat kalit YARATADI ===
d = defaultdict(int)
len(d) = 0
d['yo`q'] o'qildi → 0
len(d) = 1 ⚠️ KALIT QO'SHILDI!
✅ Kalit yaratmaydigan usullar:
'x' in d2 → False, len = 0
d2.get('x') → None, len = 0
=== 5. __missing__ — ichki mexanizm ===
d['yangi']:
__missing__('yangi') chaqirildi
→ 'sukut-yangi'
d.get('boshqa'):
→ None ⭐ __missing__ CHAQIRILMADINima ko'rsatdi: 2.4-bo'lim.
Misol 3 — Counter, ChainMap, OrderedDict
"""collections modulining lug'at turlari."""
from collections import Counter, ChainMap, OrderedDict, defaultdict
print("=== 1. Counter asoslari ===")
MATN = "Python — kuchli va oddiy dasturlash tili. Python o'rganish oson."
c = Counter(MATN.lower())
harflar = Counter(x for x in MATN.lower() if x.isalpha())
print(f" Matn: {MATN[:40]}...\n")
print(f" Eng ko'p uchraydigan harflar:")
for harf, soni in harflar.most_common(8):
print(f" {harf!r} {'█' * soni} {soni}")
sozlar = Counter(MATN.lower().replace(".", "").replace("—", "").split())
print(f"\n So'zlar:")
for soz, soni in sozlar.most_common(5):
print(f" {soz:<14} {soni}")
print(f"\n Statistika:")
print(f" Jami belgilar: {c.total()}")
print(f" Noyob belgilar: {len(c)}")
print(f" Jami harflar: {harflar.total()}")
print(f" Noyob harflar: {len(harflar)}")
print("\n=== 2. Counter metodlari ===")
c1 = Counter(a=3, b=1, c=2)
c2 = Counter(a=1, b=2, d=1)
print(f" c1 = {dict(c1)}")
print(f" c2 = {dict(c2)}\n")
AMALLAR = [
("c1 + c2", c1 + c2, "yig'indi"),
("c1 - c2", c1 - c2, "ayirma (manfiylarsiz)"),
("c1 & c2", c1 & c2, "minimum"),
("c1 | c2", c1 | c2, "maksimum"),
]
for kod, natija, izoh in AMALLAR:
print(f" {kod:<12} {str(dict(natija)):<32} {izoh}")
print(f"\n ⚠️ subtract — manfiylarni SAQLAYDI:")
c3 = Counter(a=3, b=1)
c3.subtract(Counter(a=5, b=1))
print(f" Counter(a=3,b=1).subtract(Counter(a=5,b=1)) → {dict(c3)}")
c4 = Counter(a=3, b=1) - Counter(a=5, b=1)
print(f" Counter(a=3,b=1) - Counter(a=5,b=1) → {dict(c4)}")
print(f"\n elements() — sanoq bo'yicha takrorlaydi:")
print(f" list(Counter(a=3, b=1).elements()) → "
f"{list(Counter(a=3, b=1).elements())}")
print(f"\n ⭐ Yo'q kalit → 0, va QO'SHILMAYDI:")
c5 = Counter("abc")
print(f" c['z'] → {c5['z']}")
print(f" len(c) → {len(c5)} (o'zgarmadi)")
print(f"\n defaultdict bilan solishtiring:")
d = defaultdict(int)
_ = d["z"]
print(f" d['z'] → 0")
print(f" len(d) → {len(d)} ⚠️ qo'shildi")
print("\n=== 3. Counter amaliyotda ===")
print(" Anagram tekshiruvi:")
JUFTLIKLAR = [("listen", "silent"), ("olma", "amlo"), ("python", "java")]
for a, b in JUFTLIKLAR:
natija = "✅" if Counter(a) == Counter(b) else "❌"
print(f" {natija} {a!r} ↔ {b!r}")
print("\n Ikki matn o'xshashligi:")
A = "python dasturlash tili"
B = "python veb dasturlash"
ca, cb = Counter(A.split()), Counter(B.split())
umumiy = ca & cb
oxshashlik = sum(umumiy.values()) / max(sum(ca.values()), sum(cb.values()))
print(f" A: {A}")
print(f" B: {B}")
print(f" Umumiy: {dict(umumiy)}")
print(f" O'xshashlik: {oxshashlik:.2%}")
print("\n Takrorlarni topish:")
MALUMOT = [1, 2, 2, 3, 3, 3, 4]
hisob = Counter(MALUMOT)
print(f" Ma'lumot: {MALUMOT}")
print(f" Takrorlar: {{x for x, n in Counter(m).items() if n > 1}} → "
f"{ {x for x, n in hisob.items() if n > 1} }")
print(f" Bir martaliklar: { {x for x, n in hisob.items() if n == 1} }")
print("\n Inventar boshqaruvi:")
ombor = Counter(non=100, sut=50, yog=20)
buyurtma = Counter(non=30, sut=60, shakar=10)
print(f" Ombor: {dict(ombor)}")
print(f" Buyurtma: {dict(buyurtma)}")
print(f" Berilishi mumkin: {dict(ombor & buyurtma)}")
print(f" Yetishmaydi: {dict(buyurtma - ombor)}")
print(f" Qoladi: {dict(ombor - buyurtma)}")
print("\n\n=== 4. ChainMap ===")
STANDART = {"til": "uz", "tema": "yorug'", "hajm": 14, "debug": False}
FAYLDAN = {"tema": "qorong'i", "hajm": 16}
MUHITDAN = {"debug": True}
CLIDAN = {"til": "en"}
sozlamalar = ChainMap(CLIDAN, MUHITDAN, FAYLDAN, STANDART)
print(f" Qatlamlar (birinchi g'olib):")
for i, qatlam in enumerate(sozlamalar.maps):
nomlar = ["CLI", "MUHIT", "FAYL", "STANDART"]
print(f" {i}. {nomlar[i]:<10} {qatlam}")
print(f"\n Yakuniy qiymatlar:")
for kalit in sorted(sozlamalar):
# Qaysi qatlamdan
for i, qatlam in enumerate(sozlamalar.maps):
if kalit in qatlam:
manba = ["CLI", "MUHIT", "FAYL", "STANDART"][i]
break
print(f" {kalit:<10} = {str(sozlamalar[kalit]):<12} ({manba})")
print(f"\n ⭐ Nusxa yaratmaydi — asl lug'atlar o'zgarsa yangilanadi:")
FAYLDAN["hajm"] = 20
print(f" FAYLDAN['hajm'] = 20 → sozlamalar['hajm'] = {sozlamalar['hajm']}")
print(f"\n Yozish — faqat BIRINCHI lug'atga:")
sozlamalar["yangi"] = "qiymat"
print(f" sozlamalar['yangi'] = 'qiymat'")
print(f" CLIDAN = {CLIDAN} ← o'zgardi")
print(f" STANDART = {STANDART} ← o'zgarmadi")
print(f"\n new_child — vaqtinchalik qatlam:")
vaqtinchalik = sozlamalar.new_child({"debug": False, "test": True})
print(f" vaqtinchalik['debug'] = {vaqtinchalik['debug']}")
print(f" sozlamalar['debug'] = {sozlamalar['debug']} ← asl o'zgarmadi")
print(f"\n ChainMap vs birlashtirish:")
import sys
birlashtirilgan = {**STANDART, **FAYLDAN, **MUHITDAN, **CLIDAN}
print(f" ChainMap: {sys.getsizeof(sozlamalar)} B (+ havolalar)")
print(f" dict: {sys.getsizeof(birlashtirilgan)} B (to'liq nusxa)")
print("""
⭐ ChainMap: nusxa yo'q, avtomatik yangilanadi, sekinroq qidiruv
dict: bir marta birlashtiriladi, tez qidiruv, nusxa
""")
print("\n=== 5. OrderedDict — 3.7 dan keyin ===")
od1 = OrderedDict([("a", 1), ("b", 2)])
od2 = OrderedDict([("b", 2), ("a", 1)])
d1 = {"a": 1, "b": 2}
d2 = {"b": 2, "a": 1}
print(f" 1. Tenglikda tartib:")
print(f" OrderedDict(a,b) == OrderedDict(b,a) → {od1 == od2}")
print(f" dict(a,b) == dict(b,a) → {d1 == d2}")
print(f"\n 2. move_to_end:")
od = OrderedDict([("a", 1), ("b", 2), ("c", 3)])
print(f" Asl: {list(od)}")
od.move_to_end("a")
print(f" move_to_end('a'): {list(od)}")
od.move_to_end("a", last=False)
print(f" move_to_end('a', False): {list(od)}")
print(f"\n 3. popitem(last=False) — FIFO:")
od = OrderedDict([("a", 1), ("b", 2), ("c", 3)])
print(f" popitem() → {od.popitem()} (LIFO)")
print(f" popitem(last=False) → {od.popitem(last=False)} (FIFO)")
d = {"a": 1, "b": 2}
try:
d.popitem(last=False)
except TypeError as x:
print(f" dict.popitem(last=False) → ❌ {x}")
print("\n=== 6. LRU kesh — OrderedDict bilan ===")
class LRUKesh:
"""Eng kam ishlatilgan elementni chiqaradi."""
def __init__(self, hajm: int = 3):
self.hajm = hajm
self._kesh: OrderedDict = OrderedDict()
self.topildi = 0
self.topilmadi = 0
def olish(self, kalit):
if kalit not in self._kesh:
self.topilmadi += 1
return None
self.topildi += 1
self._kesh.move_to_end(kalit) # ⭐ eng yangi qilish
return self._kesh[kalit]
def qoyish(self, kalit, qiymat):
if kalit in self._kesh:
self._kesh.move_to_end(kalit)
self._kesh[kalit] = qiymat
if len(self._kesh) > self.hajm:
eskisi = self._kesh.popitem(last=False) # ⭐ FIFO
return eskisi
return None
def __repr__(self):
return f"LRU{list(self._kesh)}"
kesh = LRUKesh(hajm=3)
AMALLAR = [
("qoyish", "a", 1), ("qoyish", "b", 2), ("qoyish", "c", 3),
("olish", "a", None),
("qoyish", "d", 4),
("olish", "b", None),
("olish", "a", None),
("qoyish", "e", 5),
]
print(f" Hajm: 3\n")
print(f" {'Amal':<16} {'Natija':<12} Kesh holati")
print(" " + "─" * 52)
for amal, kalit, qiymat in AMALLAR:
if amal == "qoyish":
chiqarilgan = kesh.qoyish(kalit, qiymat)
natija = f"↳{chiqarilgan[0]}" if chiqarilgan else "—"
print(f" qoyish({kalit!r}, {qiymat}) {natija:<12} {kesh}")
else:
n = kesh.olish(kalit)
natija = "✅ topildi" if n is not None else "❌ yo'q"
print(f" olish({kalit!r}) {natija:<12} {kesh}")
print(f"\n Statistika: {kesh.topildi} topildi, {kesh.topilmadi} topilmadi "
f"({kesh.topildi / (kesh.topildi + kesh.topilmadi):.0%})")
print("""
⭐ move_to_end + popitem(last=False) — LRU ning yuragi.
functools.lru_cache ham shu g'oyaga asoslangan.
""")Natijaning muhim qismi:
=== 2. Counter metodlari ===
c1 + c2 {'a': 4, 'b': 3, 'c': 2, 'd': 1} yig'indi
c1 - c2 {'a': 2, 'c': 2} ayirma (manfiylarsiz)
c1 & c2 {'a': 1, 'b': 1} minimum
c1 | c2 {'a': 3, 'b': 2, 'c': 2, 'd': 1} maksimum
=== 6. LRU kesh — OrderedDict bilan ===
Amal Natija Kesh holati
────────────────────────────────────────────────────
qoyish('a', 1) — LRU['a']
qoyish('b', 2) — LRU['a', 'b']
qoyish('c', 3) — LRU['a', 'b', 'c']
olish('a') ✅ topildi LRU['b', 'c', 'a']
qoyish('d', 4) ↳b LRU['c', 'a', 'd']
olish('b') ❌ yo'q LRU['c', 'a', 'd']Nima ko'rsatdi: 2.5, 2.6-bo'limlar.
Misol 4 — Amaliy: log tahlilchisi
"""dict metodlari bilan real vazifa: server loglarini tahlil qilish."""
import re
import random
from collections import Counter, defaultdict
from datetime import datetime, timedelta
print("=== Server loglari tahlilchisi ===\n")
# Soxta loglar generatsiyasi
random.seed(42)
YOLLAR = ["/", "/maqola", "/maqola/python", "/api/users", "/api/posts",
"/login", "/static/app.js", "/admin"]
USULLAR = ["GET"] * 8 + ["POST"] * 3 + ["PUT", "DELETE"]
KODLAR = [200] * 15 + [304] * 3 + [404] * 4 + [500] * 2 + [301, 403]
IPLAR = [f"192.168.1.{i}" for i in range(1, 15)]
boshlanish = datetime(2026, 9, 8, 10, 0, 0)
LOGLAR = []
for i in range(500):
vaqt = boshlanish + timedelta(seconds=random.randrange(3600))
LOGLAR.append(
f'{random.choice(IPLAR)} - [{vaqt.strftime("%d/%b/%Y:%H:%M:%S")}] '
f'"{random.choice(USULLAR)} {random.choice(YOLLAR)} HTTP/1.1" '
f'{random.choice(KODLAR)} {random.randrange(100, 50000)}'
)
NAQSH = re.compile(
r'(?P<ip>[\d.]+) - \[(?P<vaqt>[^\]]+)\] '
r'"(?P<usul>\w+) (?P<yol>\S+) [^"]*" '
r'(?P<kod>\d+) (?P<hajm>\d+)'
)
class LogTahlilchisi:
def __init__(self):
self.yozuvlar: list[dict] = []
self.notogri = 0
# Turli hisoblagichlar
self.kodlar = Counter()
self.yollar = Counter()
self.usullar = Counter()
self.iplar = Counter()
# Guruhlar
self.yol_kodlari = defaultdict(Counter)
self.ip_yollari = defaultdict(set)
self.soatlar = defaultdict(int)
# Trafik
self.yol_hajmi = defaultdict(int)
def qosh(self, qator: str) -> bool:
mos = NAQSH.match(qator)
if not mos:
self.notogri += 1
return False
y = mos.groupdict()
y["kod"] = int(y["kod"])
y["hajm"] = int(y["hajm"])
y["vaqt"] = datetime.strptime(y["vaqt"], "%d/%b/%Y:%H:%M:%S")
self.yozuvlar.append(y)
self.kodlar[y["kod"]] += 1
self.yollar[y["yol"]] += 1
self.usullar[y["usul"]] += 1
self.iplar[y["ip"]] += 1
self.yol_kodlari[y["yol"]][y["kod"]] += 1
self.ip_yollari[y["ip"]].add(y["yol"])
self.soatlar[y["vaqt"].hour] += 1
self.yol_hajmi[y["yol"]] += y["hajm"]
return True
@property
def xato_foizi(self) -> float:
xatolar = sum(n for k, n in self.kodlar.items() if k >= 400)
return xatolar / len(self.yozuvlar) * 100 if self.yozuvlar else 0.0
def muammoli_yollar(self, chegara: float = 20.0) -> dict[str, float]:
"""Xato foizi chegaradan yuqori bo'lgan yo'llar."""
natija = {}
for yol, kodlar in self.yol_kodlari.items():
jami = sum(kodlar.values())
xatolar = sum(n for k, n in kodlar.items() if k >= 400)
foiz = xatolar / jami * 100
if foiz >= chegara:
natija[yol] = foiz
return dict(sorted(natija.items(), key=lambda x: -x[1]))
def shubhali_iplar(self, chegara: int = 40) -> dict[str, int]:
return {ip: n for ip, n in self.iplar.items() if n >= chegara}
t = LogTahlilchisi()
for qator in LOGLAR:
t.qosh(qator)
print(f"=== 1. Umumiy statistika ===\n")
print(f" Jami so'rovlar: {len(t.yozuvlar):,}")
print(f" Noto'g'ri qator: {t.notogri}")
print(f" Noyob IP: {len(t.iplar)}")
print(f" Noyob yo'l: {len(t.yollar)}")
print(f" Xato foizi: {t.xato_foizi:.1f}%")
print(f" Jami trafik: {sum(t.yol_hajmi.values()) / 1024 / 1024:.2f} MB")
print(f"\n\n=== 2. Javob kodlari ===\n")
TOIFALAR = {2: "Muvaffaqiyat", 3: "Yo'naltirish", 4: "Mijoz xatosi", 5: "Server xatosi"}
toifa_hisobi = Counter(k // 100 for k in t.kodlar.elements())
jami = sum(t.kodlar.values())
print(f" {'Kod':>5} {'Soni':>6} {'Foiz':>7} Grafik")
print(" " + "─" * 48)
for kod, soni in sorted(t.kodlar.items()):
foiz = soni / jami * 100
belgi = "✅" if kod < 400 else "❌"
print(f" {belgi}{kod:>4} {soni:>6} {foiz:>6.1f}% {'█' * int(foiz / 2)}")
print(f"\n Toifalar bo'yicha:")
for toifa, soni in sorted(toifa_hisobi.items()):
print(f" {toifa}xx {TOIFALAR[toifa]:<16} {soni:>5} "
f"({soni / jami:>5.1%})")
print(f"\n\n=== 3. Eng ko'p so'ralgan yo'llar ===\n")
print(f" {'Yo`l':<22} {'So`rov':>7} {'Trafik':>10} {'O`rtacha':>10}")
print(" " + "─" * 54)
for yol, soni in t.yollar.most_common():
hajm = t.yol_hajmi[yol]
print(f" {yol:<22} {soni:>7} {hajm / 1024:>8.1f}KB "
f"{hajm / soni / 1024:>8.1f}KB")
print(f"\n\n=== 4. Muammoli yo'llar ===\n")
muammoli = t.muammoli_yollar(chegara=15)
if muammoli:
print(f" {'Yo`l':<22} {'Xato %':>8} Kodlar")
print(" " + "─" * 56)
for yol, foiz in muammoli.items():
kodlar = dict(sorted(t.yol_kodlari[yol].items()))
print(f" {yol:<22} {foiz:>7.1f}% {kodlar}")
else:
print(f" ✅ Muammoli yo'l yo'q")
print(f"\n\n=== 5. IP tahlili ===\n")
print(f" Eng faol IP lar:")
print(f" {'IP':<16} {'So`rov':>7} {'Noyob yo`l':>11} Grafik")
print(" " + "─" * 52)
for ip, soni in t.iplar.most_common(6):
noyob = len(t.ip_yollari[ip])
print(f" {ip:<16} {soni:>7} {noyob:>11} {'█' * (soni // 3)}")
shubhali = t.shubhali_iplar(chegara=45)
if shubhali:
print(f"\n ⚠️ Shubhali faollik (45+ so'rov):")
for ip, soni in sorted(shubhali.items(), key=lambda x: -x[1]):
yollar = t.ip_yollari[ip]
print(f" {ip:<16} {soni:>4} so'rov, {len(yollar)} yo'l")
print(f"\n\n=== 6. Vaqt bo'yicha taqsimot ===\n")
if t.soatlar:
eng_ko_p = max(t.soatlar.values())
print(f" {'Soat':>6} {'So`rov':>7} Grafik")
print(" " + "─" * 46)
for soat in sorted(t.soatlar):
soni = t.soatlar[soat]
uzunlik = int(soni / eng_ko_p * 30)
print(f" {soat:>4}:00 {soni:>7} {'█' * uzunlik}")
print(f"\n\n=== 7. Ishlatilgan naqshlar ===\n")
print("""
Counter(...) — kodlar, yo'llar, usullar, IP lar sanash
defaultdict(Counter) — yo'l → kod → soni (ikki darajali)
defaultdict(set) — IP → noyob yo'llar
defaultdict(int) — soat → so'rovlar soni
most_common(n) — reyting
elements() — toifalar bo'yicha qayta guruhlash
{k: v for ... if shart} — filtrlash
sorted(d.items(), key=) — tartiblash
⭐ Har bir vazifa uchun to'g'ri tuzilmani tanlash —
kodni qisqa VA tez qiladi.
""")Natijaning muhim qismi:
=== 1. Umumiy statistika ===
Jami so'rovlar: 500
Noto'g'ri qator: 0
Noyob IP: 14
Noyob yo'l: 8
Xato foizi: 28.0%
Jami trafik: 11.65 MB
=== 2. Javob kodlari ===
Kod Soni Foiz Grafik
────────────────────────────────────────────────
✅ 200 282 56.4% ████████████████████████████
✅ 301 28 5.6% ██
✅ 304 50 10.0% █████
❌ 403 16 3.2% █
❌ 404 88 17.6% ████████
❌ 500 36 7.2% ███
=== 4. Muammoli yo'llar ===
Yo`l Xato % Kodlar
────────────────────────────────────────────────────────
/admin 20.3% {200: 43, 301: 2, 304: 6, 403: 1, 404: 7, 500: 5}Nima ko'rsatdi: 2.4, 2.5-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
"setdefault faqat o'qiydi" |
Yo'q bo'lsa qo'shadi |
| "Sukut qiymat faqat kerak bo'lganda hisoblanadi" | Doim hisoblanadi |
"update yangi lug'at qaytaradi" |
None. d1 | d2 — yangi |
"update chuqur birlashtiradi" |
Sayoz — ichki lug'at almashtiriladi |
"defaultdict[k] kalit yaratmaydi" |
Yaratadi |
"Counter[k] kalit yaratadi" |
Yaratmaydi, 0 qaytaradi |
"Counter - manfiy sanoqlarni saqlaydi" |
Tushiradi. subtract saqlaydi |
"OrderedDict 3.7+ da keraksiz" |
3 farq qoldi: tenglik, move_to_end, FIFO |
"dict.clear() O(n)" |
O(1). list.clear() — O(n) |
6. Keng tarqalgan xatolar va yechimlari
1. update natijasini o'zlashtirish
d = d.update({"a": 1}) # ❌ d = None
d.update({"a": 1}) # ✅
yangi = d | {"a": 1} # ✅2. setdefault da qimmat sukut
d.setdefault(k, qimmat()) # ⚠️ har safar chaqiriladi
if k not in d: # ✅
d[k] = qimmat()3. defaultdict da tekshirish
if d[k]: # ⚠️ kalit yaratadi
if k in d: # ✅
if d.get(k): # ✅4. Counter ni siklda yangilash
c = Counter()
for x in m: c[x] += 1 # ⚠️ sekin
c = Counter(m) # ✅ C darajasida5. Chuqur birlashtirish kutish
d1.update(d2) # ⚠️ ichki lug'at almashtiriladi
chuqur_birlashtir(d1, d2) # ✅ rekursiv funksiya6. defaultdict ni funksiyaga uzatish
def f(d):
return d[kalit] # ⚠️ defaultdict bo'lsa kalit yaratadi
def f(d):
return d.get(kalit) # ✅ xavfsiz7. Counter ni dict deb hisoblash
c = Counter("abc")
c["z"] # 0, KeyError emas
if c["z"]: # ✅ ishlaydi
if "z" in c: # ✅ False8. ChainMap ga yozish
cm["kalit"] = 1 # ⚠️ faqat BIRINCHI lug'atga
cm.maps[1]["kalit"] = 1 # ✅ aniq qatlamga7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 6.10-dars (o'tilgan):
dictasoslari - 6.12-dars: tartib va
OrderedDicttarixi - 6.16-dars: lug'at generatorlari —
{k: v for ...} - 7-qism:
**kwargs, sukut argumentlar - 8-qism:
__missing__,dictdan meros,UserDict - 10-qism:
functools.lru_cache— LRU implementatsiyasi - 15-qism:
collectionsmoduli to'liq - 18-qism: profillash — qaysi tuzilma tezroq
8. Eng yaxshi amaliyotlar
Sanash —
Counter(iterable). C darajasida, eng tez.Guruhlash —
defaultdict(list).setdefault— ikkinchi tanlov.defaultdictda tekshirish uchuninyokiget.d[k]kalit yaratadi.Sukut qiymat qimmat bo'lsa
if k not in d. Argumentlar doim hisoblanadi.Qatlamlar uchun
ChainMap. Nusxa yaratmaydi, avtomatik yangilanadi.LRU/FIFO uchun
OrderedDict.move_to_endvapopitem(last=False).Chuqur birlashtirish uchun rekursiv funksiya.
updatesayoz.Natijani qaytaruvchi funksiyada
dict(defaultdict). Chaqiruvchini ajablantirmang.
9. Amaliy topshiriq
Vazifa 1: Natijani bashorat qiling
d = {"a": 1}
1. print(d.get("b"), d)
2. print(d.setdefault("b", 0), d)
3. print(d.pop("a", 9), d)
4. print({"a":1}.update({"b":2}))
5. from collections import defaultdict
dd = defaultdict(int); _ = dd["x"]; print(len(dd))
6. from collections import Counter
c = Counter("ab"); _ = c["z"]; print(len(c))
7. print(Counter(a=1) - Counter(a=3))
8. c = Counter(a=1); c.subtract(Counter(a=3)); print(c)
9. print(Counter("listen") == Counter("silent"))
10. from collections import OrderedDict
print(OrderedDict(a=1,b=2) == OrderedDict(b=2,a=1))
11. print(dict(a=1,b=2) == dict(b=2,a=1))
12. d1={"a":{"x":1,"y":2}}; d1.update({"a":{"x":9}}); print(d1)Javoblar
None {'a': 1}—geto'zgartirmaydi0 {'a': 1, 'b': 0}—setdefaultqo'shadi1 {'b': 0}—popo'chiradi;'b'2-banddasetdefaultbilan qo'shilgan (bandlar ketma-ket, bittadustida)None—updatehech narsa qaytarmaydi1—defaultdictkalit yaratdi2—CounteryaratmadiCounter()— manfiylar tushirildiCounter({'a': -2})—subtractsaqlaydiTrue— anagramFalse— tartib muhimTrue—dictda tartib muhim emas{'a': {'x': 9}}—'y'yo'qoldi (sayoz)
Vazifa 2: Xatolarni tuzating
1. d = d.update({"a": 1})
2. d.setdefault(k, qimmat_hisob())
3. dd = defaultdict(int)
if dd[k]: ...
4. c = Counter()
for x in m: c[x] += 1
5. d1.update(d2) # ichma-ich saqlanishi kerak
6. guruh = {}
for x in m:
if kalit(x) not in guruh: guruh[kalit(x)] = []
guruh[kalit(x)].append(x)
7. natija = defaultdict(list)
return natija # funksiyadan qaytarishJavoblar
1. d.update({"a": 1})
2. if k not in d: d[k] = qimmat_hisob()
3. if k in dd: ... # yoki if dd.get(k):
4. c = Counter(m)
5. d1 = chuqur_birlashtir(d1, d2)
6. guruh = defaultdict(list)
for x in m: guruh[kalit(x)].append(x)
7. return dict(natija)Vazifa 3: Chuqur birlashtirish
Funksiya yozing:
def chuqur_birlashtir(*lugatlar, royxat_qoshish=False) -> dict:- Ichma-ich lug'atlarni rekursiv birlashtiring
royxat_qoshish=Truebo'lsa ro'yxatlarni birlashtiringNoneqiymatlarni e'tiborsiz qoldirish opsiyasi- Konfliktlar ro'yxatini qaytarish
- Chuqurlik chegarasi (
max_daraja)
Vazifa 4: Ko'p funksiyali hisoblagich
Counter ni kengaytiring:
eng_kam(n)— eng kam uchraganlarfoizlar()— har birining ulushientropiya()— Shannon entropiyasigistogramma(kenglik)— matn grafigifiltrla(min_soni)— chegaradan yuqorilarbirlashtir(*boshqalar, usul="sum")—sum/max/min
Vazifa 5: Ko'p darajali indeks
Sinf yozing:
qosh(yozuv, *kalitlar)— ixtiyoriy darajali guruhlasholish(*kalitlar)— qisman kalit bilan hamsanash(*kalitlar)— har darajadagi sonlartekislash()—{(k1, k2): [...]}shakligaxulosa(funksiya)— har guruh uchun agregatsiya- Chiroyli daraxt chiqarish
Vazifa 6: Kesh tizimi
Uch kesh strategiyasini amalga oshiring va solishtiring:
- LRU — eng kam ishlatilgan (
OrderedDict) - LFU — eng kam chaqirilgan (
Counter) - TTL — muddat bilan (
dict+ vaqt) - Har biri uchun:
olish,qoyish, statistika - Bir xil ish yuklamasida topilish foizini solishtiring
functools.lru_cachebilan solishtiring
Vazifa 7: O'ylash
Nega Counter[k] yo'q kalit uchun 0 qaytaradi va kalitni qo'shmaydi, defaultdict(int)[k] esa 0 qaytaradi va qo'shadi? Qaysi biri to'g'riroq?
Javob
Ikkalasi ham to'g'ri — turli vazifalar uchun.
Counter — o'qish uchun optimallashtirilgan.
Sanoq semantikasida "uchramagan element" va "0 marta uchragan element" — bir xil narsa. Shuning uchun:
c = Counter("abc")
c["z"] # 0 — "z hech qachon uchramadi"Kalitni qo'shish ma'nosiz bo'lardi: lug'at "0 marta uchragan" barcha element bilan to'lib ketardi:
# Agar Counter kalit yaratsa:
c = Counter("abc")
for harf in "abcdefghijklmnopqrstuvwxyz":
if c[harf] > 5: # faqat o'qish
...
print(len(c)) # 26! ← 23 tasi keraksizBu — real muammo. Counter ni tekshirish sikllarida ishlatish juda keng tarqalgan.
Amalga oshirish:
class Counter(dict):
def __missing__(self, kalit):
return 0 # ⭐ self[kalit] = 0 YO'Qdefaultdict — yozish uchun optimallashtirilgan.
defaultdict ning asosiy qo'llanishi — to'plash:
d = defaultdict(list)
d["a"].append(1) # d["a"] qaytargan ro'yxat
# SAQLANISHI kerak!Agar defaultdict kalitni saqlamasa:
# Tasavvur qiling: saqlamaydi
d = defaultdict(list)
d["a"].append(1) # yangi [] yaratildi, 1 qo'shildi
print(d) # {} — ro'yxat yo'qoldi!Ya'ni defaultdict majburan kalitni saqlashi kerak — aks holda uning asosiy vazifasi ishlamaydi.
Amalga oshirish:
class defaultdict(dict):
def __missing__(self, kalit):
if self.default_factory is None:
raise KeyError(kalit)
qiymat = self.default_factory()
self[kalit] = qiymat # ⭐ SAQLANADI
return qiymatBu — asosiy farq va u ataylab qilingan.
Counter |
defaultdict |
|
|---|---|---|
| Asosiy vazifa | O'qish (sanoq) | Yozish (to'plash) |
d[yo'q] |
0, saqlamaydi |
Sukut, saqlaydi |
+= ishlaydi |
||
.append() ishlaydi |
(int) | |
| Tekshirish xavfsizmi |
Amaliy tavsiya:
# Sanash → Counter
hisob = Counter(malumot)
if hisob["kamdan-kam"] > 10: # ✅ xavfsiz
# To'plash → defaultdict
guruhlar = defaultdict(list)
guruhlar[kalit].append(x) # ✅
# defaultdict ni tekshirishda ehtiyot
if kalit in guruhlar: # ✅
if guruhlar[kalit]: # ⚠️ kalit yaratadiUchinchi variant — dict.get:
d = {}
d.get(k, 0) # 0, saqlamaydi
d.get(k, []) # [], saqlamaydi — lekin append yo'qoladiget — Counter ga o'xshaydi, lekin har safar sukut qiymatni qayta yaratadi.
Xulosa: bu — API dizaynining yaxshi namunasi. Ikki sinf bir xil __missing__ mexanizmiga tayanadi, lekin turli semantika tanlagan — chunki ular turli vazifalar uchun. "Bir o'lcham hammaga" yechim ikkalasini ham yomonlashtirardi.
Nimani mustahkamlaydi: 2.2, 2.4, 2.5-bo'limlar.
Xulosa
Bu darsda dict metodlarini va collections turlarini o'rgandik.
Eng muhim uch fikr:
get,setdefault,pop— uchta turli xatti-harakat.geto'qiydi,setdefaultyo'q bo'lsa qo'shadi,popo'chiradi. Va uchalasida ham sukut qiymat doim hisoblanadi — qimmat bo'lsaif k not in dishlating.Counter— sanash uchun,defaultdict— to'plash uchun.Counter[k]kalit yaratmaydi (o'qish xavfsiz),defaultdict[k]yaratadi (chunki.append()ishlashi kerak).Counter(iterable)— C darajasida, eng tez sanash usuli.updatesayoz vaNoneqaytaradi. Ichma-ich lug'atlar to'liq almashtiriladi — chuqur birlashtirish uchun rekursiv funksiya kerak. Yangi lug'at kerak bo'lsad1 | d2.
Keyingi darsda lug'at va tartib mavzusini chuqurlashtiramiz: ixcham lug'at tuzilishi, OrderedDict bilan farqlar va tartibga tayanadigan naqshlar.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!