10 β Tip ko'rsatmalari va map/filter¶
Python o'zgaruvchi turini oldindan e'lon qilishni talab qilmaydi. Lekin tip ko'rsatmalari (type hints) yozish β kodni o'qishni osonlashtiradi, muharring (VS Code va h.k.) yordamini yaxshilaydi va xatolarni erta topishga ko'maklashadi. Bu modulda type hints'ni va funksional uslubdagi map/filterni o'rganasan.
Bu modulda: tip ko'rsatmalari (
int,str,list[int]...),Optional/| None, vamap/filter.
10.1 Tip ko'rsatmalari β asoslari¶
O'zgaruvchi yoki funksiya parametriga uning turini yozib qo'yasan. Bu Python'ni o'zgartirmaydi β faqat "bu yerga shu tur kutilmoqda" deb belgilaydi:
ism: str = "Aziz"
yosh: int = 25
narx: float = 19.99
faolmi: bool = True
def salomla(ism: str) -> str: # ism β str, qaytaradi β str
return f"Salom, {ism}"
-> str qismi β funksiya nima qaytarishini bildiradi. Hech narsa qaytarmasa -> None:
Juda muhim: tip ko'rsatmalari Python tomonidan tekshirilmaydi. Quyidagi kod xato bermaydi:
Ular faqat hujjat va muharrir/vosita uchun. Lekin baribir doim yoz β kod ancha tushunarli bo'ladi va muharrir xatolarni ko'rsatadi.
Quyidagi diagramma annotatsiyaning har bir qismi nimani bildirishini va Python uni tekshirmasligini ko'rsatadi:
10.2 To'plamlar uchun tip ko'rsatmalari¶
Ro'yxat, lug'at va boshqalar uchun ichidagi turni ham ko'rsatasan:
ismlar: list[str] = ["Ali", "Vali"] # str'lardan iborat ro'yxat
sonlar: list[int] = [1, 2, 3] # int'lardan
narxlar: dict[str, float] = {"olma": 1.5} # kalit str, qiymat float
koordinata: tuple[int, int] = (10, 20) # ikkita int
def jami(sonlar: list[int]) -> int:
return sum(sonlar)
10.3 Optional / | None β "qiymat bo'lmasligi ham mumkin"¶
Ba'zan funksiya qiymat qaytaradi yoki hech narsa (None) qaytaradi. Buni | None bilan ko'rsatasan:
def topish(ismlar: list[str], qidiruv: str) -> int | None:
for i, ism in enumerate(ismlar):
if ism == qidiruv:
return i # topildi β indeks
return None # topilmadi β None
# `enumerate` β ro'yxat bo'ylab indeks bilan birga aylanish:
for indeks, qiymat in enumerate(["a", "b", "c"]):
print(indeks, qiymat) # 0 a, 1 b, 2 c
int | Noneβ "int yoki None" degani. Bu "qiymat bor yoki yo'q" holatlarni aniq ifodalaydi. (Eski koddaOptional[int]ko'rishing mumkin β bir xil ma'no.)
10.4 map β har elementga funksiya qo'llash¶
map ro'yxatning har bir elementiga funksiyani qo'llaydi:
sonlar = [1, 2, 3, 4]
# Har birini kvadratga:
kvadratlar = list(map(lambda x: x ** 2, sonlar))
print(kvadratlar) # [1, 4, 9, 16]
# Tayyor funksiya bilan β har birini matnga aylantirish:
matnlar = list(map(str, sonlar))
print(matnlar) # ['1', '2', '3', '4']
map har elementga bir xil funksiyani qo'llaydi va element soni o'zgarmaydi β quyidagi diagrammada bu ko'rinadi:
lambdanima?lambdaβ nomsiz, qisqa funksiya.lambda x: x ** 2= "x ni olib, kvadratini qaytaradi". Faqat bitta ifoda uchun ishlatiladi. Ko'p hollarda comprehension o'qilishi osonroq (pastga qara).
10.5 filter β shartga mos elementlarni tanlash¶
filter faqat shart True bo'lgan elementlarni qoldiradi:
sonlar = [1, 2, 3, 4, 5, 6]
juftlar = list(filter(lambda x: x % 2 == 0, sonlar))
print(juftlar) # [2, 4, 6]
Diagrammada shart True bo'lgan elementlar o'tishi, qolganlari tushib qolishi ko'rsatilgan:
Maslahat: ko'p hollarda
map/filtero'rniga comprehension (3-moduldan) o'qilishi osonroq:kvadratlar = [x ** 2 for x in sonlar] # map o'rniga juftlar = [x for x in sonlar if x % 2 == 0] # filter o'rnigamap/filterni asosan tayyor funksiya bor bo'lganda ishlat (map(str, sonlar)). Comprehension'ni esa odat qil β u Pythonda eng keng tarqalgan.
Comprehension qanday o'qilishini quyidagi oqim diagrammasi yordamida tushunish oson β aylanish, ixtiyoriy shart va ifoda ketma-ketligi:
10.6 Ilg'or mavzular (hozircha qisqacha)¶
Tip ko'rsatmalari bo'yicha yana ko'p narsa bor β keyinroq o'rganasan:
- mypy β kodni ishga tushirmasdan tip xatolarini topuvchi vosita.
- Generic, Protocol, TypedDict β murakkab loyihalar uchun kuchli tip vositalari.
- functools moduli β reduce, partial kabi funksional vositalar.
Hozircha asosiy ko'rsatmalar (int, str, list[int], | None) va map/filter yetadi.
βοΈ Masalalar (20 ta)¶
Bu masalalar oldingi modullarga tayanadi.
Oson (1β7):
kop(a: int, b: int) -> intfunksiyasini tip ko'rsatmalari bilan yoz, ko'paytirsin.salomla(ism: str) -> stryoz: "Salom, {ism}" qaytarsin.ortacha(sonlar: list[float]) -> floatyoz: o'rtachani qaytarsin.mapbilan["1","2","3"]ni[1,2,3]ga aylantir (intishlat).filterbilanrange(20)dan 3 ga bo'linadiganlarini ol.- 4-masalani comprehension bilan ham yoz, ikkalasini taqqosla.
chiqar(matn: str) -> Noneyoz: matnni chop etsin (hech narsa qaytarmasin).
O'rta (8β14):
list[int]qabul qiladigan funksiya yoz: ro'yxatning yig'indisini qaytarsin.topish(ismlar: list[str], qidiruv: str) -> int | Noneyoz: indeksni yokiNoneqaytarsin.enumeratebilan ro'yxat elementlarini "0: olma", "1: banan" ko'rinishida chiqar.mapbilan har bir ismni katta harfga aylantir (str.upperishlat).filterbilan ismlar ro'yxatidan uzunligi 4 dan katta bo'lganlarini ol.dict[str, int]qaytaradigan funksiya yoz: so'zlar ro'yxatidan har so'z uzunligini lug'at qilib qaytarsin.mapvalambdabilan har bir narxga 20% chegirma qo'llab yangi ro'yxat yasa.
Murakkab (15β20):
Callableishlat:qolla(funk, royxat)yoz β har elementga funksiyani qo'llab yangi ro'yxat qaytarsin (from typing import Callable).filter+mapni birga ishlat: ro'yxatdagi juft sonlarni olib, har birini kvadratga aylantir.- Tip ko'rsatmalari bilan to'liq funksiya yoz:
talabalar: list[dict]qabul qilsin, ballari 60 dan yuqorilarning ismlarinilist[str]qilib qaytarsin. int | Noneqaytaradigan "xavfsiz bo'lish" funksiyasini yoz: nolga bo'lishdaNoneqaytarsin.- Comprehension va
map/filterbilan bir xil natijani uch xil usulda yoz (1β100 dan juft sonlarning kvadratlari), uchalasi bir xil natija berishini tekshir. - To'liq tipli kichik dastur:
Talabama'lumotlari (dict) ro'yxatini olib, o'rtacha ball, eng yuqori ballli talaba ismi va o'tganlar (60+) sonini qaytaradigan funksiyalar yoz.
β Yechimlar¶
Ko'rsatish uchun ochish
# 1
def kop(a: int, b: int) -> int:
return a * b
print(kop(3, 4)) # 12
# 2
def salomla(ism: str) -> str:
return f"Salom, {ism}"
# 3
def ortacha(sonlar: list[float]) -> float:
return sum(sonlar) / len(sonlar)
# 4
print(list(map(int, ["1", "2", "3"]))) # [1, 2, 3]
# 5
print(list(filter(lambda x: x % 3 == 0, range(20)))) # [0,3,6,9,12,15,18]
# 6
print([int(x) for x in ["1", "2", "3"]]) # comprehension β o'qilishi osonroq
# 7
def chiqar(matn: str) -> None:
print(matn)
# 8
def jami(sonlar: list[int]) -> int:
return sum(sonlar)
print(jami([10, 20, 30])) # 60
# 9
def topish(ismlar: list[str], qidiruv: str) -> int | None:
for i, ism in enumerate(ismlar):
if ism == qidiruv:
return i
return None
print(topish(["a", "b", "c"], "b")) # 1
# 10
for i, x in enumerate(["olma", "banan"]):
print(f"{i}: {x}")
# 11
print(list(map(str.upper, ["ali", "vali"]))) # ['ALI', 'VALI']
# 12
ismlar = ["Ali", "Malika", "Bobur", "Gul"]
print(list(filter(lambda s: len(s) > 4, ismlar))) # ['Malika', 'Bobur']
# 13
def uzunliklar(sozlar: list[str]) -> dict[str, int]:
return {s: len(s) for s in sozlar}
print(uzunliklar(["olma", "non"])) # {'olma': 4, 'non': 3}
# 14
narxlar = [100, 200, 300]
print(list(map(lambda n: n * 0.8, narxlar))) # [80.0, 160.0, 240.0]
# 15
from typing import Callable
def qolla(funk: Callable[[int], int], royxat: list[int]) -> list[int]:
return [funk(x) for x in royxat]
print(qolla(lambda x: x + 1, [1, 2, 3])) # [2, 3, 4]
# 16
sonlar = [1, 2, 3, 4, 5, 6]
natija = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, sonlar)))
print(natija) # [4, 16, 36]
# 17
def otganlar(talabalar: list[dict]) -> list[str]:
return [t["ism"] for t in talabalar if t["ball"] >= 60]
data = [{"ism": "Aziz", "ball": 85}, {"ism": "Gul", "ball": 50}]
print(otganlar(data)) # ['Aziz']
# 18
def xavfsiz_bol(a: int, b: int) -> float | None:
if b == 0:
return None
return a / b
print(xavfsiz_bol(10, 2), xavfsiz_bol(10, 0)) # 5.0 None
# 19
a = [x ** 2 for x in range(1, 101) if x % 2 == 0]
b = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, range(1, 101))))
c = []
for x in range(1, 101):
if x % 2 == 0:
c.append(x ** 2)
print(a == b == c) # True
# 20
def ortacha_ball(talabalar: list[dict]) -> float:
return sum(t["ball"] for t in talabalar) / len(talabalar)
def eng_yuqori(talabalar: list[dict]) -> str:
return max(talabalar, key=lambda t: t["ball"])["ism"]
def otganlar_soni(talabalar: list[dict]) -> int:
return len([t for t in talabalar if t["ball"] >= 60])
data = [{"ism": "Aziz", "ball": 85}, {"ism": "Gul", "ball": 55}, {"ism": "Bobur", "ball": 72}]
print(ortacha_ball(data)) # 70.66...
print(eng_yuqori(data)) # Aziz
print(otganlar_soni(data)) # 2
β Generatorlar va dekoratorlar | Boshlovchilar README β | Keyingi: Standart kutubxona β