Pythonda Generator nədir

Proqramlaşdırmada yeni bir mövzunu dərinləməsinə qavramaq üçün dörd sadə sual kifayətdir:
-
Real həyatda hansı prosesə və ya obyektə bənzəyir?
-
Necə işləyir? Hardware səviyyəsində hansı proseslər baş verir?
-
Hansı problemləri həll edir, sənə praktik olaraq harada yararlı ola biler?
-
Sintaksisi və işlənmə qaydası necədir?
Bu yazıda Python-un generator anlayışını bu suallar üzərində izah edəcəyik.
Generator real həyatda nəyə bənzəyir?
Təsəvvür edin, siz aktyorsunuz. Sizin əlinizdə 1 milyon simvoldan ibarət, 150 min sözlük bir ssenari var. Rejissor sizə deyir: "Bunu kamera qarşısında subtitr olmadan, kəsintisiz səsləndirməlisiniz".
Sizin iki variantınız var:
- Əzbərləmə yolu: Bütün mətni saatlarla, bəlkə günlərlə öncədən öyrənir, əzbərləyirsiniz. Bu halda siz aktyor olaraq çoxlu yaddaş (RAM) istifadə etmiş olursunuz
- Cümlə-cümlə səsləndirmək: Rejissor "action" deyəndə sizə bir cümlə verilir, onu deyirsiniz, sonra növbəti. Siz yalnız 1 cümləlik yaddaşdan istifadə edirsiniz. RAM-da yük yoxdur
Proqramlaşdırmada bu ikinci yanaşma lazy evaluation adlanır və generator anlayışının əsas məntiqidir.
Generator necə işləyir?
"ssenari.txt" faylında 150 min söz, 1 milyon simvol var. Bu sözlərdən 10 mini böyük hərflə başlayır. Bizim məqsədimiz bu sözləri kompüterə oxutmaq və RAM-da saxlamaq ya da emal etməkdir.
- List istifədə edərək
def get_capitalized_words_line_based(filename):
capitalized_words = []
with open(filename, "r", encoding="utf-8") as f:
for line in f:
for word in line.split():
if word.istitle():
capitalized_words.append(word)
return capitalized_words
capitalized_words_list = get_capitalized_words_line_based("ssenari.txt")
-Generator istifədə edərək
def capitalized_words_generator(filename):
with open(filename, "r", encoding="utf-8") as f:
for line in f:
for word in line.split():
if word.istitle():
yield word
gen = capitalized_words_generator("ssenari.txt")
next(gen)
Hardware səviyyəsində nələr baş verir?
- Hər iki yanaşma faylı sətir-sətir RAM-a oxuyur.
- split metodu öz işini görür.
- istitle funksiyası hər bir söz üzərində yoxlanılır.
Buraya qədər RAM istifadəsi eynidir. Fərqlər if blokundan sonra başlayır:
List də:
- 10.000 söz list -də saxlanılır
- Hər söz ~55 bayt 10.000 × 55 = 550.000 bayt = ~537 KB RAM
Generator da:
- yield tapıldıqda RAM-da sətirlik müvəqqəti obyekt saxlanılır
- next çağırıldıqda: yeni söz RAM-a gəlir, öncəki silįnir
- RAM-da eyni anda yalnız bir dəyər olur
Generator sənə praktik harada yararlı ola bilər?
Generator istifadəsi böyük faylı birdəfəyə oxumaq əvəzinə RAM-ı doldurmadan sətir-sətir oxuyur, RAM sabit qalır.İstifadə olunmayan datanı RAM-da saxlamır. yield lazım olan anda verir.
Generatorların yaradılma yolları (sintaksis)
- Generator Expression (qısa)
gen = (x for x in range(100) if x % 2 == 0)
- yield istinadlı funksiyalar
def even_numbers(limit):
for i in range(limit):
if i % 2 == 0:
yield i
gen = even_numbers(100)