41 / 59

Python Generators

Generatorlar bilan tanishish

Pythonda, generator — aylanib chiqilganda qiymatlar ketma-ketligini ishlab chiqaruvchi iteratorni qaytaruvchi funksiya.

Generatorlar katta hajmdagi qiymatlar ketma-ketligini ishlab chiqarishni xohlaganimizda, lekin ularning barchasini bir vaqtning o'zida xotirada saqlashni xohlamaganimizda foydali.

Python generatorini yaratish

Pythonda, oddiy funksiyani aniqlashga o'xshab, generator funksiyasini def kalit so'zi yordamida aniqlashimiz mumkin, lekin return operatori o'rniga yield operatoridan foydalanamiz.

example.py
def generator_name(arg):
    # operatorlar
    yield something

Bu yerda, yield kalit so'zi generatordan qiymat ishlab chiqarish uchun ishlatiladi.

Generator funksiyasi chaqirilganda, u funksiya tanasini darhol bajarmaydi. Buning o'rniga, u qiymatlarni ishlab chiqarish uchun aylanib chiqilishi mumkin bo'lgan generator obyektini qaytaradi.

Misol: Python generatori

Mana sonlar ketma-ketligini ishlab chiqaruvchi generator funksiyasiga misol,

example.py
def my_generator(n):

    # hisoblagichni ishga tushirish
    value = 0

    # hisoblagich n dan kichik bo'lguncha aylanish
    while value < n:

        # hisoblagichning joriy qiymatini ishlab chiqarish
        yield value

        # hisoblagichni oshirish
        value += 1

# my_generator tomonidan ishlab chiqarilgan generator obyekti bo'ylab aylanib chiqish
for value in my_generator(3):

    # generator ishlab chiqargan har bir qiymatni chop etish
    print(value)

Natija

kod
0
1
2

Yuqoridagi misolda, my_generator() generator funksiyasi n integerini argument sifatida oladi va while sikli yordamida 0dan n-1gacha sonlar ketma-ketligini ishlab chiqaradi.

yield kalit so'zi generatordan qiymat ishlab chiqarish va keyingi qiymat so'ralguncha generator funksiyasining bajarilishini to'xtatib turish uchun ishlatiladi.

for sikli my_generator() ishlab chiqargan generator obyekti bo'ylab aylanib chiqadi, print operatori esa generator ishlab chiqargan har bir qiymatni chop etadi.

Biz shuningdek generator funksiyasidan generator obyektini boshqa har qanday funksiya kabi chaqirish orqali ham yaratishimiz mumkin,

example.py
generator = my_range(3)
print(next(generator))  # 0
print(next(generator))  # 1
print(next(generator))  # 2

Eslatma: Ko'proq bilish uchun, range() va for loop() sahifalariga tashrif buyuring.

Python generator ifodasi

Pythonda, generator ifodasi generator obyektini yaratishning ixcham usuli.

U list comprehension'ga o'xshaydi, lekin ro'yxat yaratish o'rniga, u generator ichidagi qiymatlarni ishlab chiqarish uchun aylanib chiqilishi mumkin bo'lgan generator obyektini yaratadi.

Generator ifodasi sintaksisi

Generator ifodasi quyidagi sintaksisga ega,

kod
(ifoda for element iterable'da)

Bu yerda, ifoda — iterable'dagi har bir element uchun qaytariladigan qiymat.

Generator ifodasi aylanib chiqilganda, iterable'dagi har bir element uchun ifodaning qiymatlarini birma-bir ishlab chiqaruvchi generator obyektini yaratadi.

2-misol: Python generator ifodasi

example.py
# generator obyektini yaratish
squares_generator = (i * i for i in range(5))

# generator bo'ylab aylanib chiqish va qiymatlarni chop etish
for i in squares_generator:
    print(i)

Natija

kod
0
1
4
9
16

Bu yerda, biz aylanib chiqilganda 0 dan 4gacha bo'lgan sonlarning kvadratlarini ishlab chiqaradigan generator obyekti yaratdik.

Va keyin, generator bo'ylab aylanib chiqish va qiymatlarni olish uchun for siklidan foydalandik.

Python generatorlarining qo'llanilishi

Generatorlarni kuchli implementatsiya qiluvchi bir necha sabab bor.

1. Amalga oshirish oson

Generatorlarni ularning iterator klassi hamkasbiga qaraganda aniqroq va ixchamroq tarzda amalga oshirish mumkin. Quyida 2ning darajalari ketma-ketligini iterator klassi yordamida amalga oshirishga misol keltirilgan.

example.py
class PowTwo:
    def __init__(self, max=0):
        self.n = 0
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        if self.n > self.max:
            raise StopIteration

        result = 2 ** self.n
        self.n += 1
        return result

Yuqoridagi dastur cho'zilgan va chalkash edi. Endi, keling xuddi shuni generator funksiyasi yordamida bajaramiz.

example.py
def PowTwoGen(max=0):
    n = 0
    while n < max:
        yield 2 ** n
        n += 1

Generatorlar tafsilotlarni avtomatik kuzatib borgani uchun, implementatsiya ixcham va ancha tozaroq bo'ldi.

2. Xotiraga tejamkor

Ketma-ketlikni qaytaruvchi oddiy funksiya natijani qaytarishdan oldin butun ketma-ketlikni xotirada yaratadi. Agar ketma-ketlikdagi elementlar soni juda katta bo'lsa, bu haddan tashqari ortiqcha.

Bunday ketma-ketliklarning generator implementatsiyasi xotiraga do'stona va afzal ko'riladi, chunki u bir vaqtning o'zida faqat bitta elementni ishlab chiqaradi.

3. Cheksiz oqimni ifodalash

Generatorlar cheksiz ma'lumotlar oqimini ifodalash uchun ajoyib vositalar. Cheksiz oqimlarni xotirada saqlab bo'lmaydi, va generatorlar bir vaqtning o'zida faqat bitta elementni ishlab chiqargani uchun, ular cheksiz ma'lumotlar oqimini ifodalashi mumkin.

Quyidagi generator funksiyasi barcha juft sonlarni (kamida nazariy jihatdan) generatsiya qilishi mumkin.

example.py
def all_even():
    n = 0
    while True:
        yield n
        n += 2

4. Generatorlarni quvur (pipeline) qilish

Bir nechta generatorlardan bir qator amallarni quvurlash (pipelining) uchun foydalanish mumkin. Buni misol bilan eng yaxshi tushuntirish mumkin.

Aytaylik, bizda Fibonachchi qatoridagi sonlarni ishlab chiqaruvchi generator bor. Va bizda sonlarni kvadratga oshiruvchi boshqa generator bor.

Agar Fibonachchi qatoridagi sonlarning kvadratlari yig'indisini topmoqchi bo'lsak, buni generator funksiyalarining natijasini birga quvurlash orqali quyidagi tarzda qilishimiz mumkin.

example.py
def fibonacci_numbers(nums):
    x, y = 0, 1
    for _ in range(nums):
        x, y = y, x+y
        yield x

def square(nums):
    for num in nums:
        yield num**2

print(sum(square(fibonacci_numbers(10))))

# Natija: 4895

Bu quvurlash samarali va o'qish oson (va, ha, ancha zo'r!).

QBilimingizni sinab ko'ring
1 / 3

1. Generator funksiyasini oddiy funksiyadan ajratib turuvchi kalit so'z qaysi?