collections — Counter, defaultdict, deque, namedtuple
Muammodan boshlaylik
Uch xil kod — har biri tez-tez yoziladi:
# 1. sanash
hisob = {}
for soz in sozlar:
if soz not in hisob:
hisob[soz] = 0
hisob[soz] += 1
# 2. guruhlash
guruhlar = {}
for t in talabalar:
if t["guruh"] not in guruhlar:
guruhlar[t["guruh"]] = []
guruhlar[t["guruh"]].append(t["ism"])
# 3. oxirgi 100 ta hodisa
oxirgilar = []
oxirgilar.append(hodisa)
if len(oxirgilar) > 100:
oxirgilar.pop(0) # sekin — butun ro'yxat suriladi
collections moduli bu vazifalar uchun maxsus, tez va qisqa konteynerlarni beradi.
Hayotiy o'xshatma
Oddiy quti (dict, list) — har narsaga yaraydi. Lekin oshxonada maxsus idishlar ham bor: tuxum uchun katakli quti, ziravorlar uchun aylanuvchi javon. Ular oddiy qutining ishini qilmaydi, lekin o'z ishini ancha qulay bajaradi.
Counter — sanash
from collections import Counter
sozlar = "olma nok olma uzum nok olma anor".split()
hisob = Counter(sozlar)
print(hisob) # Counter({'olma': 3, 'nok': 2, 'uzum': 1, 'anor': 1})
print(hisob["olma"]) # 3
print(hisob["banan"]) # 0 — yo'q kalit uchun KeyError emas
print(hisob.most_common(2)) # [('olma', 3), ('nok', 2)]
harflar = Counter("assalomu alaykum")
print(harflar.most_common(3)) # [('a', 4), ('s', 2), ('l', 2)]
Yangilash va amallar
savdo = Counter({"olma": 10, "nok": 5})
savdo.update({"olma": 3, "uzum": 7})
print(savdo) # Counter({'olma': 13, 'uzum': 7, 'nok': 5})
kecha = Counter(olma=10, nok=5)
bugun = Counter(olma=7, nok=8)
print(kecha + bugun) # Counter({'olma': 17, 'nok': 13})
print(kecha - bugun) # Counter({'olma': 3}) — manfiylar tashlab yuboriladi
print(sum(savdo.values())) # jami: 25
print(savdo.total()) # Python 3.10+: 25
Amaliy: eng ko'p sotilgan mahsulotlar, eng faol foydalanuvchilar, so'z chastotasi, takrorlanishlarni topish.
emaillar = ["a@x.uz", "b@x.uz", "a@x.uz"]
takrorlar = [e for e, son in Counter(emaillar).items() if son > 1]
defaultdict — standart qiymatli dictionary
from collections import defaultdict
guruhlar = defaultdict(list)
for t in talabalar:
guruhlar[t["guruh"]].append(t["ism"]) # kalit yo'q bo'lsa — avtomatik []
print(dict(guruhlar))
# {'A': ['Lola', 'Bobur'], 'B': ['Aziz']}
defaultdict(fabrika) — mavjud bo'lmagan kalitga murojaat qilinganda fabrika() chaqirilib, natija avtomatik qo'yiladi.
| Fabrika | Standart qiymat | Qachon |
|---|---|---|
list |
[] |
Guruhlash |
int |
0 |
Sanash, yig'indi |
set |
set() |
Noyob qiymatlarni guruhlash |
dict |
{} |
Ichma-ich tuzilma |
lambda: "noma'lum" |
"noma'lum" |
O'z standart qiymatingiz |
tushum = defaultdict(int)
for kategoriya, summa in sotuvlar:
tushum[kategoriya] += summa
[!WARNING]
defaultdictda faqat o'qish ham kalitni yaratadi:if guruhlar["Z"]:— endi lug'atda"Z": []paydo bo'ldi. Kalit borligini tekshirish uchun —"Z" in guruhlar, yoki oddiydict.get().
deque — ikki tomonlama navbat
from collections import deque
navbat = deque(["Lola", "Aziz"])
navbat.append("Bobur") # oxiriga
navbat.appendleft("Sardor") # boshiga
print(navbat.popleft()) # Sardor — boshidan olish
print(navbat.pop()) # Bobur — oxiridan
| Amal | list |
deque |
|---|---|---|
| Oxiriga qo'shish/olish | Tez | Tez |
| Boshiga qo'shish/olish | Sekin (hamma elementlar suriladi) | Tez |
| Indeks bo'yicha o'rtasidan | Tez | Sekinroq |
Navbat (FIFO) uchun — deque, list.pop(0) emas.
Cheklangan uzunlik — maxlen
oxirgi_qidiruvlar = deque(maxlen=5)
for soz in ["python", "django", "flask", "fastapi", "numpy", "pandas"]:
oxirgi_qidiruvlar.append(soz)
print(oxirgi_qidiruvlar) # deque(['django', 'flask', 'fastapi', 'numpy', 'pandas'], maxlen=5)
To'lganda eng eskisi avtomatik chiqib ketadi — "oxirgi N ta" uchun ideal: loglar, tarix, harakatlanuvchi o'rtacha.
navbat.rotate(1) # elementlarni aylantirish
namedtuple — nomli maydonli tuple
from collections import namedtuple
Nuqta = namedtuple("Nuqta", ["x", "y"])
Talaba = namedtuple("Talaba", "ism yosh guruh")
p = Nuqta(3, 4)
print(p.x, p.y) # 3 4 — nom bilan
print(p[0]) # 3 — indeks bilan ham
t = Talaba("Lola", 20, "A")
print(t) # Talaba(ism='Lola', yosh=20, guruh='A')
ism, yosh, guruh = t # unpacking
t2 = t._replace(yosh=21) # o'zgarmas — yangi nusxa
print(t._asdict()) # {'ism': 'Lola', 'yosh': 20, 'guruh': 'A'}
- Tuple kabi o'zgarmas va yengil
t[1]o'rnigat.yosh— o'qishli- Funksiyadan bir nechta qiymat qaytarishda (12-dars) — aniqroq
[!TIP] Zamonaviy kodda
namedtupleo'rniga ko'pinchatyping.NamedTuple(tur ko'rsatkichlari bilan) yoki@dataclass(49-dars, o'zgaruvchan bo'lishi mumkin, metodlar qo'shish oson) ishlatiladi:class Nuqta(NamedTuple): x: float; y: float
OrderedDict va ChainMap — qisqacha
from collections import OrderedDict, ChainMap
# Python 3.7+ da oddiy dict ham tartibni saqlaydi;
# OrderedDict — move_to_end() va tartibga sezgir solishtirish uchun
od = OrderedDict(a=1, b=2)
od.move_to_end("a")
# bir nechta lug'atni bitta ko'rinishda qidirish (birinchisi ustun)
sozlama = ChainMap(cli_argumentlar, muhit_ozgaruvchilari, standart)
Amaliy misol — log tahlili
from collections import Counter, defaultdict, deque
loglar = [
"10:01 ERROR db ulanish uzildi",
"10:02 INFO foydalanuvchi kirdi",
"10:03 ERROR db ulanish uzildi",
"10:04 WARN sekin so'rov",
"10:05 ERROR to'lov rad etildi",
]
darajalar = Counter(q.split()[1] for q in loglar)
xatolar = defaultdict(list)
oxirgi_3 = deque(maxlen=3)
for q in loglar:
vaqt, daraja, *xabar = q.split()
if daraja == "ERROR":
xatolar[" ".join(xabar)].append(vaqt)
oxirgi_3.append(q)
print(darajalar.most_common()) # [('ERROR', 3), ('INFO', 1), ('WARN', 1)]
for xabar, vaqtlar in xatolar.items():
print(f"{xabar}: {len(vaqtlar)} marta ({', '.join(vaqtlar)})")
print(list(oxirgi_3))
Tez-tez uchraydigan xatolar
list.pop(0) bilan navbat — katta ro'yxatda sekin; deque.popleft().
defaultdict da o'qish kalit yaratadi — in bilan tekshiring.
namedtuple ni o'zgartirishga urinish:
t.yosh = 21 # ❌ AttributeError
t = t._replace(yosh=21) # ✅
Xulosa
collections — tez-tez uchraydigan vazifalar uchun tayyor konteynerlar.
Eslab qoling:
Counter— sanash;most_common(n), yo'q kalit — 0,+/-defaultdict(list/int/set)— guruhlash va yig'ish; o'qish ham kalit yaratadideque— ikki tomondan tez; navbat —popleft();maxlen— "oxirgi N ta"namedtuple— nomli maydonli o'zgarmas tuple;_replace,_asdict- Zamonaviy alternativa —
typing.NamedTuple,@dataclass
Keyingi dars
44-dars: re — regular expressions, match, search, findall, sub, groups