Python Jeneratörlerini nasıl ve neden kullanmalısınız?

Üreteçler , PEP 255 ile tanıtıldıklarından beri Python'un önemli bir parçası olmuştur.

Üreteç işlevleri, bir yineleyici gibi davranan bir işlevi bildirmenize izin verir.

Programcıların hızlı, kolay ve temiz bir şekilde yineleyici yapmalarına izin verir.

Yineleyici nedir diye sorabilirsiniz?

Bir yineleyici üzerine tekrarlanır (ilmek) olabilir bir amacıdır. Yinelenebilir bir nesne gibi davranmasını sağlamak için bir veri kabını soyutlamak için kullanılır. Muhtemelen zaten her gün birkaç yinelenebilir nesne kullanıyorsunuz: birkaç isim vermek için dizeler, listeler ve sözlükler.

Yineleyici, Yineleyici Protokolünü uygulayan bir sınıf tarafından tanımlanır . Bu protokol, sınıf içinde iki yöntem arar: __iter__ve __next__.

Whoa, geri çekil. Neden yineleyici yapmak isteyesiniz?

Hafıza alanı tasarrufu

Yineleyiciler, somutlaştırıldığında her öğenin değerini hesaplamaz. Sadece siz istediğinizde hesaplarlar. Bu, tembel değerlendirme olarak bilinir.

Tembel değerlendirme, hesaplamak için çok büyük bir veri kümeniz olduğunda kullanışlıdır. Tüm veri seti hesaplanırken verileri hemen kullanmaya başlamanızı sağlar.

Diyelim ki, maksimum sayıdan küçük olan tüm asal sayıları elde etmek istiyoruz.

Önce bir sayının asal olup olmadığını kontrol eden işlevi tanımlarız:

def check_prime(number): for divisor in range(2, int(number ** 0.5) + 1): if number % divisor == 0: return False return True

Ardından, __iter__ve __next__yöntemlerini içerecek yineleyici sınıfını tanımlarız :

class Primes: def __init__(self, max): self.max = max self.number = 1
 def __iter__(self): return self
 def __next__(self): self.number += 1 if self.number >= self.max: raise StopIteration elif check_prime(self.number): return self.number else: return self.__next__()

Primesbir maksimum değerle somutlaştırılır. Bir sonraki üssü ondan büyük veya ona eşitse max, yineleyici bir StopIterationistisna oluşturacak ve bu da yineleyiciyi sonlandıracaktır.

Yineleyicide bir sonraki öğeyi istediğimizde, number1 artar ve asal sayı olup olmadığını kontrol eder. Değilse , asal __next__olana kadar tekrar arayacaktır number. Bir kez, yineleyici sayıyı döndürür.

Yineleyici kullanarak hafızamızda asal sayıların bir listesini oluşturmuyoruz. Bunun yerine, her talep ettiğimizde bir sonraki asal sayıyı oluşturuyoruz.

Hadi deneyelim:

primes = Primes(100000000000)
print(primes)
for x in primes: print(x)
---------
235711...

PrimesNesnenin her yinelemesi __next__, bir sonraki asal sayıyı üretmeyi çağırır .

Yineleyiciler yalnızca bir kez yinelenebilir. primesTekrar yinelemeye çalışırsanız , hiçbir değer döndürülmez. Boş bir liste gibi davranacaktır.

Artık yineleyicilerin ne olduğunu ve nasıl yapıldığını bildiğimize göre, jeneratörlere geçeceğiz.

Jeneratörler

Jeneratör işlevlerinin daha basit bir şekilde yineleyiciler oluşturmamıza izin verdiğini hatırlayın.

Üreteçler bu yieldifadeyi Python'a tanıtır . returnBir değer döndürdüğü için biraz çalışır .

Aradaki fark, işlevin durumunu kaydetmesidir . İşlev bir sonraki çağrıldığında, çalıştırma, üretilmeden önce sahip olduğu aynı değişken değerleriyle kaldığı yerden devam eder .

Bizim dönüşümü Eğer Primesbir jeneratör haline yineleyici, bu gibi bakacağız:

def Primes(max): number = 1 while number < max: number += 1 if check_prime(number): yield number
primes = Primes(100000000000)
print(primes)
for x in primes: print(x)
---------
235711...

Şimdi bu oldukça pitonik! Daha iyisini yapabilir miyiz?

Evet! PEP 289 ile tanıtılan Jeneratör İfadelerini kullanabiliriz .

Bu, jeneratörlerin liste anlama karşılığıdır. Tam olarak bir liste anlama ile aynı şekilde çalışır, ancak ifade, ()aksine ile çevrilidir [].

Aşağıdaki ifade, yukarıdaki oluşturucu işlevimizin yerini alabilir:

primes = (i for i in range(2, 100000000000) if check_prime(i))
print(primes)
for x in primes: print(x)
---------

    
     235711...
    

Python'daki jeneratörlerin güzelliği budur.

Özetle…

  • Üreteçler çok pitonik bir şekilde yineleyiciler oluşturmanıza izin verir.
  • Yineleyiciler, yalnızca istendiğinde yinelenebilir bir nesnenin sonraki öğesini oluşturarak tembel değerlendirmeye izin verir. Bu, çok büyük veri kümeleri için kullanışlıdır.
  • Yineleyiciler ve oluşturucular yalnızca bir kez yinelenebilir.
  • Üreteç İşlevleri Yineleyicilerden daha iyidir.
  • Jeneratör İfadeleri Yineleyicilerden daha iyidir (yalnızca basit durumlar için).

Medium'da takip edecek ilginç insanlar bulmak için Python'u nasıl kullandığıma dair açıklamama da göz atabilirsiniz.

Daha fazla güncelleme için beni Twitter'da takip edin.