ProgramlamaBackend Geliştirici

Python'da liste ifadelerinin (list comprehensions) çalışma mekanizmasını tanımlayın. List comprehension, map() işlevinden ve for döngülerinden neye göre farklıdır, her yaklaşımın artıları ve eksileri nelerdir ve yeteneksiz uygulama sırasında hangi hatalar ortaya çıkabilir?

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

Cevap.

Liste ifadeleri (list comprehensions), mevcut yinelemeli nesnelerden kısa bir sentaksla liste oluşturmaya yönelik özlü bir yöntemdir:

kareler = [x**2 for x in range(10)]

Bu ifade aşağıdaki ile eşdeğerdir:

kareler = [] for x in range(10): kareler.append(x**2)

Liste ifadelerinin birkaç avantajı vardır:

  • Kısalık ve okunabilirlik (özellikle basit dönüştürmeler için);
  • Koşullar (filter) ekleme imkanı: çiftler = [x for x in range(10) if x % 2 == 0];
  • İfadeler hemen bir liste döndürdüğü için, sonuçları daha sonra kullanılabilir.

map() ile benzerlik:

def f(x): return x**2 kareler = list(map(f, range(10)))

map, büyük verilerde C'de var olan bir işlev kullanılıyorsa daha hızlıdır ve tüm öğelere aynı işlev uygulamak için uygundur. Liste ifadeleri - yalnızca hazır işlevler değil, herhangi bir ifade için kullanılır. For döngüsü daha esnektir, ancak daha karmaşıktır.


Kandırıcı soru.

Neden [x for x in range(10)] gibi bir ifadede döngü değişkeni (x), Python2'de ifade çalıştırıldıktan sonra erişilebilirken, Python3'te erişilemez?

Cevap: Python2'de döngü değişkeni (x) list comprehension çalıştıktan sonra değerini korur. Python3'te ise "tecrit edilir" ve liste dışında erişilemez, bu da istenmeyen yan etkileri önler.

Örnek:

# Python 2.x: [x for x in range(3)] print(x) # x == 2 # Python 3.x: [x for x in range(3)] print(x) # NameError: name 'x' is not defined

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri.


Hikaye 1

Bir geliştirici büyük bir projede list comprehension ile yeni bir liste oluşturup filtrelemek istedi:

my_list = [item.transform() for item in data if item.is_valid()]

Ancak item.transform() işlemi, item.is_valid() False dönerse hata veriyordu. Ancak kontrol işlevi potansiyel yan etkilere sahipti ve sonuçta list comprehension, yan etkileri olan kısımda belirsiz bir şekilde hata oluşturdu.


Hikaye 2

Python2'den Python3'e geçişte bir geliştirici döngü değişkeninin erişilebilir kalacağından emindi:

[x for x in range(5)] print(x) # 4 almayı bekliyordu, ancak NameError aldı.

Bu, döngüsel mantıkta, değişkenin comprehension dışında talep edilen bir şekilde kalması gerektiği bir hataya yol açtı.


Hikaye 3

Açık seviye belirtmeden iç içe liste ifadelerinin kullanımı:

def flatten(matrix): return [cell for row in matrix for cell in row]

Yeni başlayanlar, yanlış dolaşım sırasından dolayı sık sık hatalar yaparlar (örneğin, [cell for cell in row for row in matrix] veya gereksiz iç içe geçme), bu da yanlış sonuca - tek boyutlu bir liste yerine iki boyutlu veya tam tersine - yol açar.