ProgramlamaVeri Mühendisi

Python'da tembel (gecikmeli) değerlendirme nasıl çalışır ve jeneratörler dışında nerelerde uygulanır? Tembel hesaplamaların avantajları nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Tembel değerlendirme (lazy evaluation), değerlerin yalnızca gerektiğinde hesaplandığı etkili programlama için anahtar bir kavramdır. Tarihsel olarak, Python'daki tüm temel yerleşik yapılar (listeler, demetler) "açgözlü" idi: tüm öğeleri önceden oluşturur ve belleğe yerleştirirler. Veri ve işleme görevleri miktarı arttıkça tembel hesaplamalara olan ihtiyaç ortaya çıkmıştır.

Sorun: Açgözlü hesaplamalar, sürekli sonuç alınabilecek yerlerde bellek ve zamanın verimsiz kullanılmasına neden olur — örneğin, uzun koleksiyonların filtrelenmesi, dönüştürülmesi veya dosyaların akışı durumunda.

Çözüm: Python'da tembel hesaplamalar için birçok araç ortaya çıkmıştır: jeneratörler, iteratörler ve standart kütüphane fonksiyonları (map, filter, zip, enumerate) ile itertools modülü. Tüm bunlar, hazır koleksiyonlar yerine bir seferde bir değer üreten "tembel" nesneler döner.

Kod örneği:

result = map(lambda x: x * x, range(100)) # bir jeneratör-iteratör döner for y in result: print(y) # değerler yineleme sırasında hesaplanır import itertools inf = itertools.count(1) for i in inf: if i > 3: break print(i) # 1, 2, 3

Anahtar özellikler:

  • Tüm öğeler bellekte saklanmaz: ihtiyaç duyuldukça hesaplanır.
  • Sonsuz veri akışları ile çalışabilir.
  • Fiziksel olarak tamamı mevcut olmayan koleksiyonları işleme alabilir (örneğin, bir ağdan gelen veri akışı).

Kandırmaca soruları.

Python3'te map/filter fonksiyonları her zaman liste mi döner?

Hayır, Python 3'te bu fonksiyonlar liste değil, iteratör döner. Liste almak için sonucu list() içinde sarmalamak gerekir.

x = map(int, ['1', '2']) # <map object> list(x) # [1, 2]

Map sonucunun uzunluğunu listeye dönüştürmeden alabilir miyiz?

Hayır, iteratör önceden içeriğinde kaç öğe olduğunu bilemez, tüm öğeler üzerinden geçilene kadar. list() ile hesaplamak gerekir, bu da tembellik avantajını ortadan kaldırır.

Python3'te range fonksiyonu açgözlü mü yoksa tembel mi?

Tembel: range, tüm diziyi saklamadan, talep edildikçe öğeleri "hesaplayan" bir "range nesnesi" oluşturur.

Tipik hatalar ve anti-paterne

  • Tembel nesneleri listeye dönüştürerek bellek tasarrufu avantajını kaybederler.
  • İteratörler ve jeneratörleri listelerle birbirinin yerine geçebileceğini düşünürler (ancak bunlar dizinlenemez veya tekrar geçirilemez).
  • Tembel nesnelere len() uygularlar ve hatalarla karşılaşırlar.

Hayattan bir örnek

Olumsuz durum

Bir betik dev bir CSV dosyasını işlerken, tüm satırların listesini list(open(f)) ile oluşturur. Büyük bir dosyada sunucu bellek yetersizliğinden "ölür".

Artılar:

  • Belirli bir satıra hızlı indeksleme.

Eksiler:

  • Yüksek bellek tüketimi.
  • Program büyük verilere ölçeklenemez.

Olumlu durum

Kod tembel işlemeyi kullanır: dosyanın satırlarına for line in open(f) iteratörü ile geçer veya geçici koleksiyonlar oluşturmadan map/filter ile işler.

Artılar:

  • Her boyutta dosyalar ile çalışma.
  • Minimum bellek kullanımı.

Eksiler:

  • Dizinle rastgele erişim gerektiğinde ayrı bir veri yapısı gerekir.