Asosiy qismga o'tish

To'plam (set) va comprehension

12-bob 23 kod bloki 1711 so'z

Bu bobda

  • takrorlanmaydigan qiymatlar to'plami — set ni
  • 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:

python3 qator
shaharlar = {"Toshkent", "Buxoro", "Toshkent", "Xiva", "Buxoro"}
print(shaharlar)
print(len(shaharlar))
Natija
{'Buxoro', 'Toshkent', 'Xiva'}
3

Ikki 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:

python3 qator
baholar = [5, 4, 5, 3, 4, 5, 2]
print(set(baholar))
print(sorted(set(baholar)))
Natija
{2, 3, 4, 5}
[2, 3, 4, 5]

Bo'sh to'plam

python3 qator
a = {}
b = set()
print(type(a), type(b))
Natija
<class 'dict'> <class 'set'>

{} — bo'sh lug'at. Bo'sh to'plam faqat set() bilan yasaladi.

Qo'shish va o'chirish:

python6 qator
s = {1, 2, 3}
s.add(4)
s.add(2)
s.discard(10)
s.remove(1)
print(s)
Natija
{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:

python14 qator
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")
Natija
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:

bash7 qator
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)
Natija
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:

python5 qator
sonlar = [1, 2, 3, 4, 5]
kvadratlar = []
for x in sonlar:
    kvadratlar.append(x * x)
print(kvadratlar)
Natija
[1, 4, 9, 16, 25]

List comprehension — xuddi shuni bitta qatorda yozish:

python3 qator
sonlar = [1, 2, 3, 4, 5]
kvadratlar = [x * x for x in sonlar]
print(kvadratlar)
Natija
[1, 4, 9, 16, 25]

O'qilishi: "sonlar dagi har bir x uchun x · x dan ro'yxat". Tuzilishi:

matn1 qator
[ ifoda  for  o'zgaruvchi  in  to'plam ]

Filtr bilan — oxiriga if:

python3 qator
ballar = [45, 88, 72, 30, 95, 61]
otganlar = [b for b in ballar if b >= 60]
print(otganlar)
Natija
[88, 72, 95, 61]
matn1 qator
[ ifoda  for  o'zgaruvchi  in  to'plam  if  shart ]

9-bobdagi "bir qatordan bir nechta son o'qish" endi bitta qator:

python2 qator
sonlar = [int(s) for s in input("Sonlar: ").split()]
print(sonlar, sum(sonlar))
Natija
Sonlar: 5 12 7 20 3
[5, 12, 7, 20, 3] 47

Yana bir nechta misol:

python5 qator
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"])
Natija
['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:

python4 qator
kvadratlar = [x * x for x in range(1, 6)]
print(kvadratlar)
print(*kvadratlar)
print(*kvadratlar, sep=", ")
Natija
[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):

python2 qator
ballar = [45, 88, 72, 30]
print(["o'tdi" if b >= 60 else "yiqildi" for b in ballar])
Natija
['yiqildi', "o'tdi", "o'tdi", 'yiqildi']

if qayerga yoziladi?

  • Filtr (ba'zi elementlarni tashlab yuborish): [x for x in r if x > 0] — if oxirida, else siz.
  • Tanlov (har bir element uchun ikki natijadan biri): [a if shart else b for x in r] — oldinda, else majburiy.

dict va set comprehension

Figurali qavs bilan — lug'at yoki to'plam:

python10 qator
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()})
Natija
{'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.

python2 qator
# 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'plam set().
  • in to'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.

12.1

Sonlar bitta qatorda berilgan. Nechta har xil son borligini chiqaring.

KirishKutilgan natija
1 2 2 3 3 33
7 7 71
5 -5 03
Yechimni ko'rish
python1 qator
print(len(set(input().split())))
12.2

Ikki qatorda ikki guruh talabalarining ismlari berilgan. Ikkala guruhda ham bor ismlarni alifbo tartibida, probel bilan chiqaring. Umumiy ism bo'lmasa — Yo'q.

KirishKutilgan natija
Ali Vali Sarvinoz, Sarvinoz Otabek AliAli Sarvinoz
A B, C DYo'q
Yechimni ko'rish
python2 qator
umumiy = set(input().split()) & set(input().split())
print(" ".join(sorted(umumiy)) if umumiy else "Yo'q")
12.3

Sonlar bitta qatorda berilgan. Ularning kvadratlarini xuddi shu tartibda chiqaring.

KirishKutilgan natija
1 2 31 4 9
-2 0 54 0 25
Yechimni ko'rish
python1 qator
print(*[int(s) ** 2 for s in input().split()])
12.4

N berilgan. 1 dan N gacha bo'lgan sonlardan 3 ga bo'linadigan, lekin 9 ga bo'linmaydiganlarini chiqaring.

KirishKutilgan natija
203 6 12 15
93 6
2
Yechimni ko'rish
python2 qator
n = int(input())
print(*[i for i in range(1, n + 1) if i % 3 == 0 and i % 9 != 0])
12.5

Gap berilgan. Har bir so'z uzunligini so'z:uzunlik ko'rinishida, so'zlar tartibida, probel bilan ajratib chiqaring.

KirishKutilgan natija
Men Python o'rganyapmanMen:3 Python:6 o'rganyapman:12
salomsalom:5
Yechimni ko'rish
python1 qator
print(" ".join(f"{s}:{len(s)}" for s in input().split()))
12.6

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.

KirishKutilgan natija
olma, lamoTrue
kitob, botikTrue
salom, salamFalse
Yechimni ko'rish
python1 qator
print(sorted(input()) == sorted(input()))

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar