CodeGym /Kurslar /Python SELF AZ /İteratorlar

İteratorlar

Python SELF AZ
Səviyyə , Dərs
Mövcuddur

5.1 IterableIterator

Artıq bildiyiniz kimi, iteratorlar — bu, iterasiya protokolunu reallaşdıran obyektlərdir ki, koleksiyadan ardıcıl olaraq elementləri əldə etməyə imkan yaradır. Iteratorlar Python-da ardıcıllıqların elementlərini keçmək üçün geniş istifadə olunur, məsələn list, tuple və string.

Gəlin iteratorların necə qurulduğunu və onlardan necə istifadə edəcəyimizi araşdıraq.

İterasiya olunabilən obyekt (Iterable)

Bir obyektin üzərində for dövrü ilə keçmək üçün, o, iterasiya olunabilən – Iterable olmalıdır. Yəni, bizim obyekt __iter__() metodunu reallaşdırmalıdır ki, bu da iterator obyektini qaytarır.

Iterator obyekt (Iterator)

Bu xüsusi bir obyekt olur ki, __next__() funksiyasına malikdir və bu funksiya ardıcıllıqda növbəti elementi qaytarır. Elementlər bitdiyi zaman, __next__() metodu iterasiyanın dayandırıldığına işarə olaraq StopIteration istisnasını atır.

Iterator həmçinin özünü qaytaran __iter__() metodunu reallaşdırmalıdır.

Python-un daxili funksiyaları ilə nümunə

Bu nümunədə numbers list iterasiya olunabilən obyekt kimi çıxış edir. Biz iteratoru iter() funksiyası ilə alırıq və next() funksiyasından istifadə edərək elementlərin üzərində StopIteration istisnası atılana qədər iterasiya edirik.


# İterasiya olunabilən obyekt
numbers = [1, 2, 3, 4, 5]
            
# İterasiya olunabilən obyektin iteratorunu əldə edirik
iterator = iter(numbers)
            
# Elementlərin üzərində iterator vasitəsilə keçiririk
try:
    while True:
        number = next(iterator)
        print(number)
except StopIteration:
    pass
        

Bu, məhz aşağıdakı kodu yazdığınız zaman baş verir:


# İterasiya olunabilən obyekt
numbers = [1, 2, 3, 4, 5]
            
for number in numbers:
    print(number)
        

5.2 Iteratorun mahiyyəti

Iterator — bu hansısa bir obyektir ki, bizə elementlər qrupunu bir-bir gəzməyə kömək edir. Onun reallaşdırılması çox fərqli şəkildə ola bilər. Gəlin öz class-ımızı yazaq və orada iterator üçün tələb olunan bütün tələbləri həyata keçirək.

Adım 1. İlk öncə öz class-ımızı yaradaq

İcazə verin, o start-dan end-ə qədər nömrələri bir-bir qaytarsın.


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        

Adım 2. __iter__ funksiya dəstəyi

İndi biz ona __iter__ funksiyasını əlavə etməliyik, hansı ki iterator obyektini qaytaracaq ki, onun üzərində __next()__ funksiyası çağırılsın. Biz öz obyektimizə istinad qaytaracağıq – bu qadağan deyil.


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        

Adım 3. __next__ funksiya dəstəyi

İndi iterator obyektimizə __next__ funksiyasını əlavə etmək lazımdır, hansı ki, növbəti elementi qaytaracaq. Biz sadəcə current dəyişənindən istifadə edəcəyik:


def __next__(self):
    current = self.current
    self.current += 1
    return current
        

Adım 4. Iteratorun dayandırılması

Əgər iterator artıq qaytarmaq istədiyi bütün dəyərləri qaytarıbsa, o StopIteration istisnası atmalıdır. Gəlin sonuncu funksiyamızı bir az dəyişək:


def __next__(self):
    if self.current >= self.end: raise StopIteration
    current = self.current
    self.current += 1
    return current
        

Əla. İndi öz iteratorumuzdan istifadə edə bilərik. Bütün kodumuzun nümunəsini göstəririk:


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        
    def __next__(self):
        if self.current >= self.end:
            raise StopIteration
        current = self.current
        self.current += 1
        return current
        
# Custom iterator-ın nümunəsini yaradırıq
my_iter = MyIterator(1, 5)
        
# Elementləri keçmək üçün iterator istifadə edirik
for num in my_iter:
    print(num)

5.3 Düzgün iterator

Əvvəlki nümunədəki iterator nə üçün yaxşı deyil? Bəli, bu bir iterator-dur, işləyir, amma çox primitivdir. Onunla eyni elementlər kolleksiyasını fərqli iteratorlarla eyni zamanda keçmək mümkün deyil.

Daha düzgün olardı ki, __iter__ metodunda özünə deyil, ayrı bir obyektə link qaytaran kod yazaq, hansı ki, düzgün şəkildə bütün elementləri qaytarar.

Nümunə:


class MyIterable:
    def __init__(self, data):
        self.data = data
    
    def __iter__(self):
        return MyIterator(self.data)
    
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        item = self.data[self.index]
        self.index += 1
        return item
    
# İstifadə
my_iterable = MyIterable([1, 2, 3, 4])
for item in my_iterable:
    print(item)
    

Bu nümunədə iki sinifimiz var — birincisinə iterator vasitəsilə keçəcəyimiz kolleksiya ötürülür. İkincisi — bu artıq iteratorun özüdür, hansı ki next() metodunda kolleksiyanın elementlərini qaytarır. O da kifayət qədər sadədir, amma iteratorları siniflərinizə əlavə etməyin düzgün yolu məhz budur.

1
Опрос
Modullar və paketlər,  19 уровень,  4 лекция
недоступен
Modullar və paketlər
Modullar və paketlər
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION