itertools — chain, combinations, permutations, product, islice

~20 daq · Python · Ilg'or mavzular

Muammodan boshlaylik

Vazifalar:

  • Uch xil ro'yxatni ketma-ket aylanib chiqish — ularni birlashtirmasdan
  • 5 kishilik jamoadan barcha mumkin bo'lgan juftliklarni tuzish (turnir jadvali)
  • Kiyim do'koni: 3 rang × 4 o'lcham × 2 material — barcha variantlar
  • Cheksiz generatordan (45-dars) birinchi 10 tasini olish — [:10] ishlamaydi

Ichma-ich sikllar va yordamchi ro'yxatlar bilan — uzun va xatolarga moyil kod. itertools — iteratorlar bilan ishlash uchun tez, tayyor "qurilish bloklari".


Hayotiy o'xshatma

Konstruktor to'plami. Har bir detal (funksiya) oddiy: ulash, takrorlash, tanlash, kesish. Ularni birlashtirib, murakkab mexanizm yig'asiz. Va barcha detallar "lazy" — mexanizm faqat kerakli qismni harakatlantiradi.


Hammasi — lazy

import itertools

natija = itertools.chain([1, 2], [3, 4])
print(natija)          # <itertools.chain object> — hali hisoblanmagan
print(list(natija))    # [1, 2, 3, 4]

itertools funksiyalari iterator qaytaradi (45-dars): qiymatlar so'ralganda hisoblanadi, bir marta ishlatiladi. Ko'rish uchun — list().


Birlashtirish va kesish

chain — ketma-ket ulash

from itertools import chain

a_sinf = ["Lola", "Aziz"]
b_sinf = ["Bobur"]
c_sinf = ["Dilnoza", "Sardor"]

for ism in chain(a_sinf, b_sinf, c_sinf):
    print(ism)

royxatlar = [[1, 2], [3], [4, 5]]
print(list(chain.from_iterable(royxatlar)))    # [1, 2, 3, 4, 5] — tekislash

a + b + c dan farqi — yangi ro'yxat yaratilmaydi.

islice — iteratorni kesish

from itertools import islice

def sonlar():
    n = 0
    while True:
        yield n
        n += 1

print(list(islice(sonlar(), 5)))          # [0, 1, 2, 3, 4]
print(list(islice(sonlar(), 10, 15)))     # [10, 11, 12, 13, 14]
print(list(islice(sonlar(), 0, 20, 5)))   # [0, 5, 10, 15]
with open("katta.log", encoding="utf-8") as f:
    for qator in islice(f, 10):      # faqat birinchi 10 qator
        print(qator, end="")

batched — partiyalar (3.12+)

from itertools import batched

for partiya in batched(range(10), 4):
    print(partiya)     # (0, 1, 2, 3)  (4, 5, 6, 7)  (8, 9)

Kombinatorika

from itertools import combinations, permutations, product

jamoa = ["Lola", "Aziz", "Bobur"]

combinations — tartibsiz tanlash

print(list(combinations(jamoa, 2)))
# [('Lola', 'Aziz'), ('Lola', 'Bobur'), ('Aziz', 'Bobur')]

Turnir: har kim har kim bilan bir marta o'ynaydi. (Lola, Aziz) va (Aziz, Lola) — bitta juftlik.

permutations — tartibli joylashtirish

print(list(permutations(jamoa, 2)))
# [('Lola', 'Aziz'), ('Lola', 'Bobur'), ('Aziz', 'Lola'),
#  ('Aziz', 'Bobur'), ('Bobur', 'Lola'), ('Bobur', 'Aziz')]

print(len(list(permutations(jamoa))))   # 6 — 3! barcha tartiblar

Tartib muhim: 1-o'rin va 2-o'rin — (Lola, Aziz) va (Aziz, Lola) — har xil natija.

product — Dekart ko'paytmasi

ranglar = ["qora", "oq"]
olchamlar = ["S", "M", "L"]

for rang, olcham in product(ranglar, olchamlar):
    print(f"{rang}-{olcham}", end=" ")
# qora-S qora-M qora-L oq-S oq-M oq-L

Ichma-ich sikllar o'rniga:

for rang in ranglar:
    for olcham in olchamlar:
        ...
print(list(product([0, 1], repeat=3)))   # 3 bitli barcha kombinatsiyalar — 8 ta
Funksiya Tartib muhimmi Takrorlash 3 dan 2 ta — soni
combinations Yo'q Yo'q 3
combinations_with_replacement Yo'q Ha 6
permutations Ha Yo'q 6
product(..., repeat=2) Ha Ha 9

[!WARNING] Kombinatorik funksiyalar natijalari soni juda tez o'sadi: 10 ta elementning barcha permutations lari — 3 628 800 ta, 20 tasiniki — 2.4 × 10¹⁸. list() ga aylantirsangiz, xotira tugaydi. Faqat aylanib chiqing va kerak bo'lganda to'xtating.


Cheksiz iteratorlar

from itertools import count, cycle, repeat

for i in count(start=1, step=2):    # 1, 3, 5, 7, ... cheksiz
    if i > 9:
        break

navbatchilar = cycle(["Lola", "Aziz", "Bobur"])
for kun in ["Du", "Se", "Ch", "Pa", "Ju"]:
    print(kun, next(navbatchilar))   # Du Lola, Se Aziz, Ch Bobur, Pa Lola, Ju Aziz

list(repeat("x", 3))                 # ['x', 'x', 'x']

Guruhlash va filtrlash

groupby

from itertools import groupby

sotuvlar = [
    ("2026-11-07", 120000), ("2026-11-07", 85000),
    ("2026-11-08", 300000), ("2026-11-08", 50000), ("2026-11-08", 25000),
]

for sana, guruh in groupby(sotuvlar, key=lambda s: s[0]):
    summalar = [s[1] for s in guruh]
    print(sana, sum(summalar), len(summalar))

[!WARNING] groupby faqat ketma-ket turgan bir xil kalitlarni guruhlaydi. Ma'lumot kalit bo'yicha saralanmagan bo'lsa — bir xil kalit bir necha guruhga bo'linib ketadi. Avval sorted(data, key=...) qiling yoki defaultdict(list) (43-dars) ishlating.

takewhile, dropwhile

from itertools import takewhile, dropwhile

harorat = [18, 21, 25, 31, 28, 19]
print(list(takewhile(lambda t: t < 30, harorat)))   # [18, 21, 25] — birinchi 30+ gacha
print(list(dropwhile(lambda t: t < 30, harorat)))   # [31, 28, 19] — undan keyin hammasi

accumulate — o'sib boruvchi natija

from itertools import accumulate

kunlik = [100, 250, 80, 300]
print(list(accumulate(kunlik)))           # [100, 350, 430, 730] — jami
print(list(accumulate(kunlik, max)))      # [100, 250, 250, 300] — shu kungacha maksimum

pairwise — qo'shni juftliklar (3.10+)

from itertools import pairwise

narxlar = [100, 120, 115, 130]
ozgarish = [b - a for a, b in pairwise(narxlar)]
print(ozgarish)      # [20, -5, 15]

Tez-tez uchraydigan xatolar

Iteratorni ikki marta ishlatish:

juftlar = combinations(jamoa, 2)
print(len(list(juftlar)))   # 3
print(list(juftlar))        # [] — tugagan

Saralanmagan ma'lumotda groupby — bir kalit bir necha guruhda.

Katta kombinatorikani list() ga aylantirish — xotira tugaydi.


Xulosa

itertools — iteratorlar uchun tez, lazy qurilish bloklari.

Eslab qoling:

  • chain, chain.from_iterable — ulash va tekislash; islice — kesish; batched — partiyalar
  • combinations (tartibsiz), permutations (tartibli), product (ichma-ich sikllar o'rniga)
  • count, cycle, repeat — cheksiz; break yoki islice bilan
  • groupby — faqat saralangan ma'lumotda
  • accumulate, pairwise, takewhile, dropwhile
  • Hammasi — bir martalik iteratorlar

Keyingi dars

47-dars: functools — partial, reduce, lru_cache