koddla

Yazılımcıları bilgi ile güçlendirir.

Python “in” ifadesi

Pythton’da “in” ifadesi birden fazla amaçla kullanılabilir. Örneğin aşağıdaki kod parçasında bir öğenin liste içerisinde olup olmadığını kontrol edebiliriz:

some_list = [1, 2, 3, 4, 5]
print(2 in some_list)

Bir sonraki örnekte ise i değerlerinin sırasıyla liste içerisindeki öğelere eşit olacağını biliyoruz:

for i in [1, 2, 3, 4, 5]:
    print(i)

Peki bu iki örnekteki in ifadesi aynı operatöre mi karşılık geliyor? in ifadesine biraz daha detaylı bakarak inceleyelim.


Yukarıdaki örneklerde kullanılan operatörler aynı konsepte sahipler. Ancak aynı operatör değiller.

print(2 in some_list) örneğindeki in operatörü birden fazla farklı durum için kullanılır. Python dökümanlarına görex in y ifadesi y.__contains__(x) metodunu çalıştırır – eğer y__contains__  metoduna sahipse.

y, bu metoda sahip değilse, x in y ifadesi bir iterasyon oluşturmaya çalışır. Bu durumda x‘in değerini ya y.__iter__() ile elde etmeye çalışır, ya da, __iter__ tanımlı değilse y.__getitem__(x) ile elde etmeyi dener.

Bir for döngüsü içerisinde in sadece döngü-indexine değer atamak için işaretleyici görevi görür. Yine Python dökümanlarına göre: for döngüsü içerisindeki in‘den sonra gelen ifade bir iteratör vermek için kullanılır. Döngü bloğu böylece iteratör içerisindeki her öğe için çalışır. for ifadesi __contains__ veya __getitem__ ile ilgilenmez.

Örneğin aşağıdaki gibi bir sınıfımız olsun:

>>> class C:
...     def __iter__(self):
...         return iter([1,2,3,4])
>>>

C sınıfı __contains__ metodunu implement etmediği için buradaki in ifadesi bir iteratör döndürür:

>>> c = C()
>>> 2 in c
True
>>> 5 in c
False

Kısaca söylersek. in ifadesinin iki tür kullanımı bulunur:

  • bir yapının içinde değerin olup olmadığını test eder (__contains__ ile)
  • bir diziyi döngüye sokar (Iterable ile)

in ifadesi hangi arama yöntemini kullanır

in operatorü ile bir dizi içerisindeki değeri kontrol ettiğimizde __contains__ fonksiyonunun çağırılacağını söyledik. Ancak bu fonksiyon farklı türler için farklı şekilde implement edilir.

strlist ve tuple için __contains__ bir linear search (O(N)) çalıştırır. C ile implement edildiği için de normalde python ile yazacağımız linear search ifadesine göre muhtemelen daha hızlıdır.

set ve dict için ise bir hash-table lookup çalıştırır ki bu daha da hızlıdır. Ortalama olarak O(1) zaman karmaşıklığına sahiptir.

Haliyle farklı türler için farklı performans özellikleri gösterecektir.

Birden fazla in ifadesi kullanımı

Peki birden fazla in ifadesi kullandığımızda ne oluyor? Örneğin aşağıdaki ifadeden ne anlamamız gerekir:

"a" in "bar" in "foo" in "baz"

Python soldan sağa doğru çalışır. Bu şekilde akışı parantezler ile kontrol edebiliriz. Yukarıdaki ifade de doğal olarak şöyle düşünülebilir:

"a" in "bar" and "bar" in "foo" and "foo" in "baz"

Ve sonuç olarak False döner.

Daha açık yazarsak;

("a" in "bar") and ("bar" in "foo") and ("foo" in "baz") – ya da  False

iki boyutlu array için in ifadesi

Aşağıdaki gibi iki boyutlu bir listemiz olsun:

x = ["Hello", "World"]
y = ["Hi", "Guys"]
z = [x, y]

z listesi, x ve y listelerini içeriyor. Peki “Hello” öğesini z içerisinde ararsak ne dönmesi gerekir:

"Hello" in z

Bu kodu çalıştırırsanız, beklentinizin aksine, False döndüğünü göreceksiniz. Peki neden?


in ifadesinin burada beklediğimiz sonucu vermesi için bir döngü kullanmamız gerekir. Çünkü "Hello" gerçekten de z‘nin içinde bulunmaz — "Hello" x‘in içerisindedir, o da z‘nin içinde:

>>> x = ["Hello", "World"]
>>> y = ["Hi", "Guys"]
>>> z = [x, y]
>>> "Hello" in x
True
>>> x in z
True
>>> any("Hello" in a for a in z)
True

Yukarıdaki kod parçasında ax ve y üzerinde döner. Eğer herhangi (any) bir öğe için Yukarıdaki kod parçasında ax ve y üzerinde döner. Eğer herhangi (any) bir öğe için "Hello" in a ifadesi sağlanırsa True döner.

Bunu yapmanın başka bir yolu da aşağıdaki kullanım olabilir:

>>> [b for a in z for b in a]
['Hello', 'World', 'Hi', 'Guys']
>>> "Hello" in (b for a in z for b in a)
True

Önceki kullanımda olduğu gibi, az‘nin içindeki tüm listeler üzerinde döner. Ancak bu döngü içerisinde bir de b ile döngü kurarız. Aynı şekilde, "Hello" in (iterable) ifadesi sağlanırsa True sonucunu alırız.

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top