To'plam (set) va comprehension
Bu bobda
- takrorlanmaydigan qiymatlar to'plami —
setni - to'plamlar ustida amallar: birlashma, kesishma, ayirma
- ro'yxatni bitta qatorda yasash — list comprehension ni
- dict va set comprehension ni
- qachon comprehension yozish kerak, qachon yo'q
set: takrorlanmaydigan to'plam
To'plam (set) — takrorlanmaydigan qiymatlar to'plami. Figurali qavsda yoziladi, lekin juftlik emas, oddiy qiymatlar:
shaharlar = {"Toshkent", "Buxoro", "Toshkent", "Xiva", "Buxoro"} print(shaharlar) print(len(shaharlar))
{'Buxoro', 'Toshkent', 'Xiva'}
3Ikki marta yozilgan shaharlar bir marta qoldi. Yana bir xususiyati: to'plamda tartib yo'q — chiqish tartibi siz yozgan tartibdan farq qilishi mumkin, indeks bilan olib ham bo'lmaydi (shaharlar[0] — xato).
Ro'yxatdagi takrorlarni olib tashlashning eng qisqa yo'li:
baholar = [5, 4, 5, 3, 4, 5, 2] print(set(baholar)) print(sorted(set(baholar)))
{2, 3, 4, 5}
[2, 3, 4, 5]Bo'sh to'plam
a = {} b = set() print(type(a), type(b))
<class 'dict'> <class 'set'>
{} — bo'sh lug'at. Bo'sh to'plam faqat set() bilan yasaladi.
Qo'shish va o'chirish:
s = {1, 2, 3} s.add(4) s.add(2) s.discard(10) s.remove(1) print(s)
{2, 3, 4}add — bor qiymatni qayta qo'shmaydi. remove — yo'q qiymatda KeyError beradi, discard — jim o'tadi.
Tez qidirish
in to'plamda ro'yxatdagidan ancha tez ishlaydi: ro'yxat har bir elementni birma-bir tekshiradi, to'plam esa qiymatni darhol topadi. Ko'p marta "bormi?" deb so'ralsa, to'plam ishlating:
import time royxat = list(range(1_000_000)) toplam = set(royxat) t = time.perf_counter() for _ in range(100): 999_999 in royxat print(f"ro'yxat: {(time.perf_counter() - t) * 1000:.1f} ms") t = time.perf_counter() for _ in range(100): 999_999 in toplam print(f"to'plam: {(time.perf_counter() - t) * 1000:.3f} ms")
ro'yxat: 270.6 ms to'plam: 0.008 ms
Bu raqamlar kitob yig'ilgan kompyuterda o'lchandi; sizda boshqacha chiqadi, lekin farq doim minglab marta bo'ladi.
To'plamlar ustida amallar
Matematikadagi to'plamlar nazariyasi Pythonda tayyor:
python = {"Ali", "Vali", "Sarvinoz", "Otabek"} sql = {"Sarvinoz", "Otabek", "Javohir"} print("Ikkalasida ham: ", python & sql) print("Kamida bittasida:", python | sql) print("Faqat Pythonda: ", python - sql) print("Faqat bittasida: ", python ^ sql)
Ikkalasida ham: {'Sarvinoz', 'Otabek'}
Kamida bittasida: {'Vali', 'Ali', 'Sarvinoz', 'Javohir', 'Otabek'}
Faqat Pythonda: {'Vali', 'Ali'}
Faqat bittasida: {'Vali', 'Ali', 'Javohir'}| Belgi | Metod | Nomi | Ma'nosi |
|---|---|---|---|
a & b |
a.intersection(b) |
kesishma | ikkalasida ham bor |
a \| b |
a.union(b) |
birlashma | kamida bittasida bor |
a - b |
a.difference(b) |
ayirma | a da bor, b da yo'q |
a ^ b |
a.symmetric_difference(b) |
simmetrik ayirma | faqat bittasida bor |
Chiqishda tartib sizdagidan boshqacha bo'lishi mumkin — to'plamda tartib yo'q. Kerak bo'lsa sorted() qiling.
List comprehension
9-bobda ro'yxatdan yangi ro'yxat yasashni to'rt qatorda yozgan edik:
sonlar = [1, 2, 3, 4, 5] kvadratlar = [] for x in sonlar: kvadratlar.append(x * x) print(kvadratlar)
[1, 4, 9, 16, 25]
List comprehension — xuddi shuni bitta qatorda yozish:
sonlar = [1, 2, 3, 4, 5] kvadratlar = [x * x for x in sonlar] print(kvadratlar)
[1, 4, 9, 16, 25]
O'qilishi: "sonlar dagi har bir x uchun x · x dan ro'yxat". Tuzilishi:
[ ifoda for o'zgaruvchi in to'plam ]
Filtr bilan — oxiriga if:
ballar = [45, 88, 72, 30, 95, 61] otganlar = [b for b in ballar if b >= 60] print(otganlar)
[88, 72, 95, 61]
[ ifoda for o'zgaruvchi in to'plam if shart ]
9-bobdagi "bir qatordan bir nechta son o'qish" endi bitta qator:
sonlar = [int(s) for s in input("Sonlar: ").split()] print(sonlar, sum(sonlar))
Sonlar: 5 12 7 20 3 [5, 12, 7, 20, 3] 47
Yana bir nechta misol:
ismlar = ["ali", "vali", "sarvinoz"] print([ism.capitalize() for ism in ismlar]) print([len(ism) for ism in ismlar]) print([i for i in range(1, 31) if i % 7 == 0]) print([h for h in "Men Python o'rganyapman" if h in "aeiou"])
['Ali', 'Vali', 'Sarvinoz'] [3, 4, 8] [7, 14, 21, 28] ['e', 'o', 'o', 'a', 'a', 'a']
Ro'yxat elementlarini qavs va vergulsiz, probel bilan chiqarish uchun oldiga * qo'yiladi. 10-bobdagi "ochish" ni eslang: * ro'yxatni alohida qiymatlarga ochib, print() ga beradi:
kvadratlar = [x * x for x in range(1, 6)] print(kvadratlar) print(*kvadratlar) print(*kvadratlar, sep=", ")
[1, 4, 9, 16, 25] 1 4 9 16 25 1, 4, 9, 16, 25
if-else ham bo'lishi mumkin, lekin u oldinga, ifoda o'rniga yoziladi (6-bobdagi qisqa if):
ballar = [45, 88, 72, 30] print(["o'tdi" if b >= 60 else "yiqildi" for b in ballar])
['yiqildi', "o'tdi", "o'tdi", 'yiqildi']
if qayerga yoziladi?
- Filtr (ba'zi elementlarni tashlab yuborish):
[x for x in r if x > 0]—ifoxirida,elsesiz. - Tanlov (har bir element uchun ikki natijadan biri):
[a if shart else b for x in r]— oldinda,elsemajburiy.
dict va set comprehension
Figurali qavs bilan — lug'at yoki to'plam:
ismlar = ["Ali", "Sarvinoz", "Otabek"] uzunlik = {ism: len(ism) for ism in ismlar} print(uzunlik) narxlar = {"non": 4000, "sut": 12500, "guruch": 21000} chegirma = {k: v * 0.9 for k, v in narxlar.items()} print(chegirma) gap = "men har kuni python va sql o'rganaman" print({len(s) for s in gap.split()})
{'Ali': 3, 'Sarvinoz': 8, 'Otabek': 6}
{'non': 3600.0, 'sut': 11250.0, 'guruch': 18900.0}
{2, 3, 4, 6, 10}{kalit: qiymat for ...} — lug'at, {qiymat for ...} — to'plam.
Qachon comprehension yozmaslik kerak?
Comprehension — qisqa, oddiy o'zgartirish yoki filtr uchun. Agar ichida ichma-ich if, bir nechta for yoki uzun hisob bo'lsa, oddiy for sikl o'qishga osonroq. Qoida: bir qarashda tushunilmasa — oddiy sikl yozing.
# Qiyin o'qiladi: natija = [x * y for x in range(5) if x % 2 for y in range(x) if y > 1 and x + y < 7]
Kitoblarda
- Python asoslari: Set (to'plam) 43–47-betlar.
- Python Crash Course: 4-bob, List Comprehensions 59-bet;
set()bilan takrorlarsiz yurish 6-bob, 104-bet.
Xulosa
set— takrorsiz va tartibsiz;set(r)— takrorlarni olib tashlash; bo'sh to'plamset().into'plamda juda tez.&kesishma,|birlashma,-ayirma,^simmetrik ayirma.[ifoda for x in r], filtr —[... if shart]oxirida, tanlov —[a if shart else b for ...]oldinda.{k: v for ...}— lug'at,{x for ...}— to'plam.
Mashqlar
Imkoni bo'lsa, comprehension bilan yeching.
Sonlar bitta qatorda berilgan. Nechta har xil son borligini chiqaring.
| Kirish | Kutilgan natija |
|---|---|
| 1 2 2 3 3 3 | 3 |
| 7 7 7 | 1 |
| 5 -5 0 | 3 |
Yechimni ko'rish
print(len(set(input().split())))
Ikki qatorda ikki guruh talabalarining ismlari berilgan. Ikkala guruhda ham bor ismlarni alifbo tartibida, probel bilan chiqaring. Umumiy ism bo'lmasa — Yo'q.
| Kirish | Kutilgan natija |
|---|---|
| Ali Vali Sarvinoz, Sarvinoz Otabek Ali | Ali Sarvinoz |
| A B, C D | Yo'q |
Yechimni ko'rish
umumiy = set(input().split()) & set(input().split()) print(" ".join(sorted(umumiy)) if umumiy else "Yo'q")
Sonlar bitta qatorda berilgan. Ularning kvadratlarini xuddi shu tartibda chiqaring.
| Kirish | Kutilgan natija |
|---|---|
| 1 2 3 | 1 4 9 |
| -2 0 5 | 4 0 25 |
Yechimni ko'rish
print(*[int(s) ** 2 for s in input().split()])
N berilgan. 1 dan N gacha bo'lgan sonlardan 3 ga bo'linadigan, lekin 9 ga bo'linmaydiganlarini chiqaring.
| Kirish | Kutilgan natija |
|---|---|
| 20 | 3 6 12 15 |
| 9 | 3 6 |
| 2 |
Yechimni ko'rish
n = int(input()) print(*[i for i in range(1, n + 1) if i % 3 == 0 and i % 9 != 0])
Gap berilgan. Har bir so'z uzunligini so'z:uzunlik ko'rinishida, so'zlar tartibida, probel bilan ajratib chiqaring.
| Kirish | Kutilgan natija |
|---|---|
| Men Python o'rganyapman | Men:3 Python:6 o'rganyapman:12 |
| salom | salom:5 |
Yechimni ko'rish
print(" ".join(f"{s}:{len(s)}" for s in input().split()))
Ikkita so'z berilgan. Ular anagramma bo'lsa (bir xil harflardan iborat, faqat tartibi boshqa), True, aks holda False chiqaring. Maslahat: sorted() satrning harflarini tartiblangan ro'yxat qilib beradi.
| Kirish | Kutilgan natija |
|---|---|
| olma, lamo | True |
| kitob, botik | True |
| salom, salam | False |
Yechimni ko'rish
print(sorted(input()) == sorted(input()))
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.