Generators(Üreteçler)

Merhaba arkadaşlar ,

Bugün Python generators konusuna bakıyordum ve aklıma takılan bir yer oldu . Hemen alt tarafa kodları bırakarak kodlar üzerinden sorumu soruyorum şimdiden teşekkürler.

‘’’
1.Örnek

list1 =(x for x in range(0,10))

l=list1
k=list1

print(next(l))   #0
print(next(l))   #1
print(next(l))   #2
print(next(k))   #3
print(next(k))   #4

2.Örnek

def generator():

     print(f"1.uretec : ",end="")
     yield 1
     print(f"2.uretec : ",end="")
     yield 2
     print(f"3.uretec : ",end="")
     yield  3


a=generator()
b=generator()

print(next(a))   # 1.uretec : 1
print(next(a))   # 2.uretec : 2
print(next(b))   # 1.uretec : 1

‘’’
Sorum şu ;

  1. örnekteki generator’üm için ‘l’ ve ‘k’ olarak iki değişken tanımladım ve next() fonksiyonu ile önce ‘l’ ile üç kere ardından da ‘k’ ile de iki kere fonksiyonumu çağırdım ve çıktılar 0-1-2-3-4 olarak geldi ki ‘k’ değişkenim ile çağrım yaptığımda ‘l’ değişkenimin kaldığı yerden devam etti dikkat ederseniz.
    Aynı sonucu 2.Örnek için de beklerken yani ‘a’ ve ‘b’ değişkenlerim için de benzer bir sonuç beklerken (‘b’ değişkenimi çağırdığımda ‘a’ nın kaldığı yerden sonuç döndürmesini bekliyordum.) ‘b’ değişkenim ile fonksiyonu çağırdığımda bana dönüş olarak ilk yield değeri döndü ve bu durumu henüz anlayamadım .
    Yardımcı olursanız sevinirim .
    Teşekkürler .

Her değişken için bellekte farklı yerler ayırıyor ve o değişken ile kaldığı yerden devam ediyor.

Gerçi ilk örnekte bu durum olmamış. Belirtmişsin. Bir inceleyeyim ben de.

Teşekkür ederim . Bekliyorum :smile:

Fonksiyon ve listelerde farklı işliyor. İlk örnekte tek bir liste var ve bellekte olan listeden ilerliyor. İkinci örnekte ise fonksiyon iki farklı değişkene tanımlanmış. Her değişkenin belleği ayrı gibi görünüyor. Tahminim bu yönde.

Burada bir generator var (list1) ve l ve k değişkenleri aynı generator’ı referans alıyor.

Burada ise iki farklı generator var. a ayrı, b ayrı bir generator.


Mesela burayı şöyle değiştirsek:

l=(x for x in range(0,10))
k=(x for x in range(0,10))
print(next(l))   
print(next(l))  
print(next(l))   
print(next(k))   
print(next(k))  

Çıktı:

0
1 
2
0
1

Gördüğünüz gibi artık çıktılar ikinci örnekteki gibi oldu -k'yi nextlediğimiz zaman l bundan etkilenmiyor, l'yi nextlediğimiz zaman k bundan etkilenmiyor- çünkü l ve k ayrı iki generator oldu, aynen ikinci örnekteki gibi…

Umarım anlatabilmişimdir.

1 Beğeni

Merhaba, sayın unnick’in aktardığını şu site yardımıyla visualize execution diyerek de gözlemleyebilirsiniz. Yukarıdaki programda “isimlerin” aslında hangi değerleri kastettiğini şurada görüyoruz:

image

gen_1, a_1 ve b_1'in hepsi birden aynı yere bakıyor (sizdeki list1, l ve k; ama l pek iyi bir değişken ismi değil gibi, bende 1 gibi gözüküyor neredeyse :ğ). Dolayısıyla bu 3’ünden hangisine next derseniz, alttaki (x for x in range(10)) üreteci ilerlemiş oluyor; bu üreteçten 1 tane var 3 tane değil ve hepsi onu “paylaşıyorlar”. Öbür taraftan, her gen_2() dediğinizde yeni bir üreteç elde ediyorsunuz; a_2 ve b_2'nin baktığı yerler ayRı ve birinin next'i diğerini ırgalamıyor. Ama şöyle olsaydı

g = gen_2()

a = g
b = g

Yine ilkindeki durum: tek bir üreteç var piyasada o da ilk başta g'ye atanmış. Sonra a ve b isimleri de aynı g'ye bakıyor dolayısıyla o üretece bakıyorlar. Artık bu 3’ünden hangisini next'lerseniz "diğer"leri de etkilenecektir. Çok da diğer değiller zira ayNı yere bakıyorlar. Bunu da o sitede deneyebilirsiniz!


<nitpicking>

Hayır! Liste yok orada, üreteç var…

Hayır! Fonksiyonun kendisi atanmıyor (a = gen_2'yi ima ediyor söylediğiniz [parantezsiz]).

</nitpicking>

1 Beğeni

Teşekkür ederim anladım olayı şimdi , ‘Then_Shiffman’ in aşşaıya bıraktığı linkle de gayet güzel pekişti.

Şuan tam olarak anlamış bulunmaktayım . Teşekkür ederim , vermiş olduğun link de harika ben bunu kullanırım :dancer: