Asosiy qismga o'tish

*args, **kwargs, ko'rinish sohasi va lambda

14-bob 21 kod bloki 1744 so'z

Bu bobda

  • istalgancha argument qabul qilishni: *args
  • istalgancha nomli argument qabul qilishni: **kwargs
  • lokal va global o'zgaruvchilar farqini
  • lambda — nomsiz qisqa funksiyani
  • standart qiymat sifatida ro'yxat berish tuzog'ini

*args: istalgancha argument

print() ga bitta ham, o'nta ham qiymat berish mumkin. O'z funksiyamiz ham shunday bo'lishi uchun parametr oldiga * qo'yiladi:

python7 qator
def pitsa(*qoshimchalar):
    print(f"Pitsa: {len(qoshimchalar)} ta qo'shimcha")
    for q in qoshimchalar:
        print(f"  - {q}")

pitsa("pishloq")
pitsa("qo'ziqorin", "qalampir", "zaytun")
Natija
Pitsa: 1 ta qo'shimcha
  - pishloq
Pitsa: 3 ta qo'shimcha
  - qo'ziqorin
  - qalampir
  - zaytun

*qoshimchalar — barcha argumentlarni bitta kortejga yig'adi. Nomi istalgan bo'lishi mumkin, lekin an'anaviy nomi — *args.

Oddiy parametrlar bilan birga ishlatilsa, *args oxirida turadi:

python5 qator
def pitsa(olcham, *qoshimchalar):
    print(f"{olcham} sm li pitsa: {', '.join(qoshimchalar)}")

pitsa(25, "pishloq")
pitsa(35, "qo'ziqorin", "qalampir", "zaytun")
Natija
25 sm li pitsa: pishloq
35 sm li pitsa: qo'ziqorin, qalampir, zaytun

Birinchi argument olcham ga tushdi, qolganlari qoshimchalar ga yig'ildi.

O'z sum() imizni yozamiz

python8 qator
def ortacha(*sonlar):
    if not sonlar:
        return 0
    return sum(sonlar) / len(sonlar)

print(ortacha(5, 4, 5))
print(ortacha(3))
print(ortacha())
Natija
4.666666666666667
3.0
0

**kwargs: istalgancha nomli argument

** — barcha nomli argumentlarni lug'atga yig'adi:

python7 qator
def profil(ism, familiya, **malumot):
    malumot["ism"] = ism
    malumot["familiya"] = familiya
    return malumot

p = profil("abulqosim", "rafiqov", shahar="Toshkent", soha="AI")
print(p)
Natija
{'shahar': 'Toshkent', 'soha': 'AI', 'ism': 'abulqosim', 'familiya': 'rafiqov'}

shahar va soha parametrlari funksiyada yo'q edi — ular malumot lug'atiga tushdi. An'anaviy nomi — **kwargs (keyword arguments).

Tartib qoidasi: def f(oddiy, standart=1, *args, **kwargs).

* va ** chaqiruvda: ochish

Teskari yo'nalishda ham ishlaydi: ro'yxatni * bilan, lug'atni ** bilan alohida argumentlarga ochib berish mumkin (12-bobdagi print(*r) aynan shu):

python7 qator
def uchburchak_perimetri(a, b, c):
    return a + b + c

tomonlar = [3, 4, 5]
print(uchburchak_perimetri(*tomonlar))
sozlama = {"a": 6, "b": 8, "c": 10}
print(uchburchak_perimetri(**sozlama))
Natija
12
24

Ko'rinish sohasi: lokal va global

Funksiya ichida yaratilgan o'zgaruvchi faqat o'sha funksiya ichida yashaydi. U lokal (local) o'zgaruvchi:

python5 qator
def hisobla():
    natija = 42

hisobla()
print(natija)
Xato xabari
NameError: name 'natija' is not defined

Funksiya tugaganda natija yo'qoladi. Natija tashqarida kerak bo'lsa — return qiling (13-bob).

Funksiyadan tashqarida yaratilgan o'zgaruvchi — global. Funksiya uni o'qiy oladi:

python6 qator
KURS = "Python asoslari"

def sarlavha():
    print(f"=== {KURS} ===")

sarlavha()
Natija
=== Python asoslari ===

Lekin funksiya ichida xuddi shu nomga qiymat bersangiz, Python yangi lokal o'zgaruvchi yaratadi, global o'zgarmaydi:

python8 qator
meva = "olma"

def ozgartir():
    meva = "anor"
    print("ichkarida:", meva)

ozgartir()
print("tashqarida:", meva)
Natija
ichkarida: anor
tashqarida: olma

Globalni o'zgartirish uchun global kalit so'zi bor:

python10 qator
hisoblagich = 0

def bosildi():
    global hisoblagich
    hisoblagich += 1

bosildi()
bosildi()
bosildi()
print(hisoblagich)
Natija
3

global dan qoching

global ishlaydi, lekin katta dasturda qaysi funksiya global qiymatni o'zgartirganini topish juda qiyin bo'ladi. Yaxshi usul: qiymatni parametr sifatida bering va natijani return qiling:

python7 qator
def bosildi(hisoblagich):
    return hisoblagich + 1

h = 0
h = bosildi(h)
h = bosildi(h)
print(h)
Natija
2

lambda: bitta qatorli funksiya

Ba'zan funksiya juda kichik va faqat bir joyda kerak bo'ladi. Uni def bilan yozmasdan, lambda bilan joyida yasash mumkin:

python2 qator
kvadrat = lambda x: x * x
print(kvadrat(7))
Natija
49

lambda x: x * x — "x ni oladi, x * x ni qaytaradi". return yozilmaydi, faqat bitta ifoda bo'ladi.

lambda ning asosiy joyi — sorted(), max(), min() ning key parametri (10-bobda ko'rgan edik):

python7 qator
talabalar = [("Ali", 78), ("Sarvinoz", 91), ("Otabek", 85)]
print(sorted(talabalar, key=lambda t: t[1]))
print(sorted(talabalar, key=lambda t: t[1], reverse=True))
print(max(talabalar, key=lambda t: t[1]))

sozlar = ["olma", "Python", "uy", "dasturlash"]
print(sorted(sozlar, key=lambda s: len(s)))
Natija
[('Ali', 78), ('Otabek', 85), ('Sarvinoz', 91)]
[('Sarvinoz', 91), ('Otabek', 85), ('Ali', 78)]
('Sarvinoz', 91)
['uy', 'olma', 'Python', 'dasturlash']

Lug'atlar ro'yxatini tartiblash ham shunday:

python7 qator
talabalar = [
    {"ism": "Ali", "ball": 78},
    {"ism": "Sarvinoz", "ball": 91},
    {"ism": "Otabek", "ball": 85},
]
for t in sorted(talabalar, key=lambda t: t["ball"], reverse=True):
    print(f"{t['ism']:<10}{t['ball']}")
Natija
Sarvinoz  91
Otabek    85
Ali       78

map va filter

map() — har bir elementga funksiyani qo'llaydi, filter() — shartga mos elementlarni qoldiradi:

python5 qator
sonlar = [1, 2, 3, 4, 5, 6]
print(list(map(lambda x: x * 10, sonlar)))
print(list(filter(lambda x: x % 2 == 0, sonlar)))
print([x * 10 for x in sonlar])
print([x for x in sonlar if x % 2 == 0])
Natija
[10, 20, 30, 40, 50, 60]
[2, 4, 6]
[10, 20, 30, 40, 50, 60]
[2, 4, 6]

Natija bir xil. Pythonda comprehension (12-bob) odatda o'qishga osonroq hisoblanadi, lekin map va filter ni boshqalarning kodida ko'p uchratasiz. Masalan, sonlar qatorini o'qishning mashhur yo'li: list(map(int, input().split())).

Standart qiymat sifatida ro'yxat

python7 qator
def qosh(element, royxat=[]):
    royxat.append(element)
    return royxat

print(qosh("a"))
print(qosh("b"))
print(qosh("c"))
Natija
['a']
['a', 'b']
['a', 'b', 'c']

Har safar yangi bo'sh ro'yxat kutgan edik, lekin ro'yxat o'sib bormoqda! Standart qiymat funksiya yaratilganda bir marta hisoblanadi va hamma chaqiruvlar o'sha bitta ro'yxatni ishlatadi. To'g'ri yo'l — None:

python8 qator
def qosh(element, royxat=None):
    if royxat is None:
        royxat = []
    royxat.append(element)
    return royxat

print(qosh("a"))
print(qosh("b"))
Natija
['a']
['b']

Kitoblarda

  • Python asoslari: global o'zgaruvchilar va global kalit so'zi 10–11-betlar; lambda funksiya 71-bet.
  • Python Crash Course: 8-bob, Passing an Arbitrary Number of Arguments 147–150-betlar (*toppings, **user_info).

Xulosa

  • *args — ortiqcha argumentlar kortejga, **kwargs — nomli argumentlar lug'atga.
  • Chaqiruvda f(*royxat), f(**lugat) — ochib berish.
  • Funksiya ichidagi o'zgaruvchi lokal; natijani return bilan chiqaring, global dan qoching.
  • lambda x: ifoda — key= uchun qisqa funksiya.
  • Standart qiymat sifatida [] emas, None.

Mashqlar

14.1

ortacha(*sonlar) funksiyasini yozing: istalgancha sonning o'rta arifmetigini qaytaradi, son berilmasa — 0. Bir qatorda berilgan sonlarni * bilan ochib, funksiyaga bering.

KirishKutilgan natija
5 4 54.666666666666667
1010
2 4 6 85
Yechimni ko'rish
python4 qator
def ortacha(*sonlar):
    return sum(sonlar) / len(sonlar) if sonlar else 0

print(ortacha(*[float(s) for s in input().split()]))
14.2

eng_uzun(*sozlar) funksiyasini yozing: eng uzun so'zni qaytaradi (bir xil uzunlikda bo'lsa — birinchisi). Gapdagi so'zlarni funksiyaga bering.

KirishKutilgan natija
men dasturlashni yaxshi koramandasturlashni
olma anorolma
Yechimni ko'rish
python4 qator
def eng_uzun(*sozlar):
    return max(sozlar, key=len)

print(eng_uzun(*input().split()))
14.3

Birinchi qatorda N, keyingi N qatorda ism ball berilgan. Talabalarni ball bo'yicha kamayish tartibida, ism ball ko'rinishida chiqaring. Ball teng bo'lsa — kiritilgan tartibi saqlansin.

KirishKutilgan natija
3, Ali 78, Sarvinoz 91, Otabek 85Sarvinoz 91 Otabek 85 Ali 78
2, A 5, B 5A 5 B 5
Yechimni ko'rish
python7 qator
n = int(input())
talabalar = []
for _ in range(n):
    ism, ball = input().split()
    talabalar.append((ism, int(ball)))
for ism, ball in sorted(talabalar, key=lambda t: t[1], reverse=True):
    print(ism, ball)
14.4

So'zlar bitta qatorda berilgan. Ularni uzunligi bo'yicha, uzunlik teng bo'lsa — alifbo tartibida chiqaring. Maslahat: key=lambda s: (len(s), s) — kortejlar avval birinchi, keyin ikkinchi element bo'yicha solishtiriladi.

KirishKutilgan natija
olma uy dasturlash anor otot uy anor olma dasturlash
c bb aa c bb
Yechimni ko'rish
python1 qator
print(*sorted(input().split(), key=lambda s: (len(s), s)))
14.5

hisobot(**baholar) funksiyasini yozing: nomli argumentlar fan=baho ko'rinishida keladi. Funksiya baholarning o'rtachasini 2 xona aniqlikda qaytaradi. Kiritish: bitta qatorda fan=baho juftlari. Maslahat: juftlardan lug'at yasang va ** bilan oching.

KirishKutilgan natija
matematika=5 fizika=4 ingliz=54.67
python=55.00
Yechimni ko'rish
python8 qator
def hisobot(**baholar):
    return f"{sum(baholar.values()) / len(baholar):.2f}"

juftlar = {}
for q in input().split():
    fan, baho = q.split("=")
    juftlar[fan] = int(baho)
print(hisobot(**juftlar))

Bu bobni bepul o'qidingiz.

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

Telegramda yozish Narxlar