Python’da koşul ifadeleri yazmaya if, elif veya else gibi anahtar kelimeleri kullanarak başlarız. Bu anahtar kelimeler bir boolean (True veya False) değerine bağlı olarak farklı eylemler gerçekleştirmek kullanılır. Bu bölümde, Python koşullarını, boolean mantığını ve ternary ifadeleri nasıl kullanacağımızı inceleyeceğiz.
Python’da if kullanımı
if koşul:
kod bloğu
if
ifadesini herhangi bir koşulu kontrol etmek için kullanırız. statements checks the condition. Eğer ifade True
olarak değerlendirilirse, if ifadesi içindeki kod bloğu çalıştırılır. False
olarak değerlendirildiğinde ise kod bloğu görmezden gelinir.
if True:
print "Doğru!"
>> Doğru!
if False:
print "Bu satır bastırılmaz.."
“Herhangi bir koşul”‘dan kastımız herhangi sözdizimine uygun bir ifade olmalıdır:
if 2 + 2 == 4:
print "Matematik biliyorum!"
>> Matematik biliyorum!
Doğruluk değerleri
Aşağıdaki değerler Python’da False
olarak değerlendirilir. Yani bu ifadeleri bir boolean operatörü ile koşul olarak kullandığımızda false sonucunu alırız.
- None
- False
0
, veya herhangi sıfıra eşit bir değer:0L
,0.0
,0j
- Boş dizeler:
''
,""
,()
,[]
- Boş dict:
{}
- Kullanıcı tarafından tanımlanmış
__bool__
veya__len__
metotları 0 veyaFalse
döndüren veri türleri
Python’da diğer tüm veri türleri True
olarak değerlendirilir.
Else ifadesi kullanımı
if koşul:
kod bloğu
else:
kod bloğu
else ifadesi önceki if koşullarının False döndürülmesi durumunda çalıştırılır.
if True:
print "true!"
else:
print "Bastırılmaz.."
# Output: true!
if False:
print "bastırılmaz.."
else:
print "false!"
# Output: false!
Python’da if, elif ve else kullanımı
Birden fazla koşul ifadesi tanımlamak için ilk koşulda if
ifadesini, diğer koşullar için ise elif
ifadesini kullanırız. Son olarak da yazdığımız koşullar haricinde kalan diğer ifadeleri kapsaması adına else
kullanırız.
sayi = 5
if sayi > 2:
print("Sayi 2'den büyük.")
elif sayi < 2: # isteğe bağlı koşul (birden fazla elif olabilir)
print("Sayi 2'den küçük.")
else: # isteğe bağlı koşul (tek bir else olabilir)
print("Sayı 2.")
Çıktı olarak Sayi 2'den büyük.
metnini alırız.
elif
yerine else if
kullanırsak bir söz dizimi hatası ile karşılaşırız.
Temel olarak Python’da koşul kullanımını bu şekilde özetleyebiliriz. Şimdi biraz daha gelişmiş ifadelere bakalım.
Boolean Mantık İfadeleri
Boolean mantık ifadeleri True veya False döndürmelerinin yanı sıra, True veya False olarak yorumlanan değerleri de döndürür.
and operatörü
and operatörü tüm ifadeleri değerlendirir ve tüm ifadeler True olarak değerlendirilirse son ifadeyi döndürür. Aksi takdirde False olarak değerlendirilen ilk değeri döndürür:
>>> 1 and 2 2
Tüm sayı ve karakter ifadeleri True olarak değerlendirilir demiştik. Burada True olarak değerlendirilen son ifade 2 olduğu için çıktı olarak 2’yi aldık.
>>> 1 and 0 0
Burada da benzer şekilde düşünüyoruz. Ancak, 0’ın False olarak döndürüldüğünü unutmayın. Haliyle False dönen ilk değeri çıktı olarak alıyoruz.
>>> 1 and "Hello World" "Hello World" >>> "" and "Pancakes" ""
İlk örnekte 1 ve “Hello World” ifadelerinin ikisi de True olarak dönerken, son örnekte “” ifadesi False olarak dönecek.
or operatörü
or operatörü, ifadeleri soldan sağa doğru değerlendirir. True olarak dönen ilk değeri veya hiç bir dedğer True değilse son değeri döndürür.
>>> 1 or 2 1 >>> None or 1 1 >>> 0 or [] []
Tembel değerlendirme
Bu şekilde kullanım yaptığımızda ifadelerin Python tarafından tembel bir şekilde değerlendirildiğini unutmayın. Bu şu demek; değerlendirilmesi gerekmeyen ifadeler değerlendirilmezler. Örneğin aşağıdaki ifadede 0 ilk False değer olduğu için print_me() fonksiyonu değerlendirilmeyecek.
>>> def print_me(): print('I am here!') >>> 0 and print_me() 0
Birden fazla koşulu değerlendirme
Karşılaşacağımız genel bir sorun birden fazla koşulu değerlendirirken yanlış mantığı uygulamak olabilir. Örneğin iki tane değişkenimiz olsun. Ve bu değişkenlerin ikisinin de 2’den büyük olup olmadığını kontrol edelim.
>>> a = 1
>>> b = 6
>>> if a and b > 2:
... print('yes')
... else:
... print('no')
yes
Burada ifadeyi ilk yazma eğilimimiz şu şekilde olabilir: if a and b > 2
. Ancak, bu ifade ile beklenmedik bir sonuç alırız. Çünkü ifade aslında if (a) and (b > 2)
gibi değerlendirilir ve bool(a)
değeri True
olarak döndürülür.
Bu sebeple her değişkeni ayrı ayrı karşılaştırmamız gerekir.
>>> if a > 2 and b > 2:
... print('yes')
... else:
... print('no')
no
Karşılaşacağımız bir başka hata ise bir değişkenin birden fazla değerinin kontrölü olabilir.
>>> a = 1
>>> if a == 3 or 4 or 6:
... print('yes')
... else:
... print('no')
yes
Bu ifade de ilk örneğe benzer şekilde if (a == 3) or (4) or (6)
şeklinde değerlendirilir. Böylece beklenmedik bir sonuç alabiliriz. Bunun sebebi de bool(4)
ve bool(6)
ifadelerinin True
dönmesidir. Burada da her değişkeni ayrı ayrı karşılaştırmamız gerekir:
>>> if a == 3 or a == 4 or a == 6:
... print('yes')
... else:
... print('no')
no
Burada küçük bir not düşelim. Yukarıdaki ifadeyi kurallara daha uygun bir şekilde yazmak için aslında in ifadesini kullanırız.
>>> if a in (3, 4, 6):
... print('yes')
... else:
... print('no')
no
Koşul ifadeleri ya da üçlü operatör (ternary operatör)
Üçlü operatörler satır içi koşul ifadeleri yazmak için kullanılırlar. Basit karşılaştırmalar yapmak istediğimizde ve kodun kolayca okunmasını beklediğimizde yararlıdırlar.
- Üçlü ifadeleri yazma şeklimiz diğer dillere göre farklıdır (örneğin C, Ruby, Java, vb.). Bu sebeple beklenmedik hatalar alabilirsiniz.
- Bazılarımız için bu yöntem farklı gelebilir. Çünkü normal akışa aykırı bir şekilde yazarız.
n = 5
"2'den büyük" if n > 2 else "2'den küçük veya eşit"
# Çıktı: '2'den büyük'
Tenary operatörleri birbiri içinde de kullanabiliriz:
n = 5
"Hello" if n > 10 else "Goodbye" if n > 5 else "Good day"
Ternary operatörler aynı zamanda lambda fonksiyonları için de koşul oluşturmada yararlıdır.
Liste üreteçleri ile koşul ifadeleri
Python liste üreteçleri içinde koşul ifadeleri kullanmamıza da izin verir:
[deger_false, deger_true][<koşul-testi>]
Örneğin:
>> n = 16
>> print [10, 20][n <= 15]
10
Burada n<=15
ifades False
döndürür (False değeri Python’da 0’a eşittir). Dolayısıyla Python’un değerlendirmesi aşağıdaki gibi olur:
[10, 20][n <= 15]
==> [10, 20][False]
==> [10, 20][0] #False==0, True==1
==> 10
Benzer bir yaklaşımı ilk, ikinci ve son öğeyi almak için cmp metodu ile kullanırız. Yerleşik __cmp__ metodu 3 değer döndürür: 0, 1, -1. cmp(x,y) eğer iki obje de aynı ise 0 döndürür; x > y ise 1 ve x < y ise -1. Haliyle, bu değerler, liste üretecinde ilk (index 0), ikinci (index 1) ve sonuncu (index -1) öğeyi elde etmek için kullanılabilir:
['eşit', 'büyük', 'küçük', ][cmp(x,y)]
# x,y = 1,1 çıktı: 'eşit'
# x,y = 2,1 çıktı: 'büyük'
# x,y = 1,2 çıktı: 'küçük'
Nesnenin None olduğunu kontrol etme
Çoğu durumda None olan bir nesneye bir şeyler atamak isteriz. Bunun için de, öncelikle, nesnenin None değerinde olup olmadığını kontrol ederiz. aDate
isimli bir değişkenimiz olsun:
None testi yapmak için kullanacağımız en kolay yöntem is None
testidir.
if aDate is None:
aDate = datetime.date.today()
(Not: == None
yerine is None
kullanmak daha Python-vari bir yöntemdir.)
Yukarıdaki kod aşağıdaki şekilde de yazılabilir:
if not aDate:
aDate = datetime.date.today()
Daha da Python’a uygun bir yöntem olarak ise aşağıdakini kullanırız:
aDate = aDate or datetime.date.today()
Karşılaştırma operatörleri
Koşullu ifadelerde karşılaştırmalar için kullanabileceğimiz operatörlere bakalım:
!= – ‘ye eşit değildir
== – Şuna eşittir
> – daha büyük
\< – daha az
= – eşit veya daha büyük
<= – daha az veya eşit
is – nesnelerin tam olarak aynı nesne olduğunu test eder
is not – nesnelerin tam olarak aynı nesne olmadığını test eder
Zincirlemeli Karşılaştırmalar
Zincirlemeli karşılaştırma ile birden fazla öğeyi birden fazla karşılaştırma operatörü ile karşılaştırabiliriz. Örneğin:
x > y > z
ifadesi
x > y and y > z
İfadesinin kısa bir halidir. Bu, yalnızca her iki karşılaştırma da True ise True olarak değerlendirilecektir.
Genel form şu şekildedir:
a OP b OP c OP d …
Burada OP, kullanabileceğiniz çoklu karşılaştırma işlemlerinden birini ifade ederken, harfler de rastgele geçerli ifadeleri temsil eder.
0 != 1 != 0 ifadesinin, 0 != 0 False olsa bile True olarak değerlendirildiğine dikkat edin. Bu gösterimi matematiksel olarak düşünseydik, x != y != z gösterimi x, y ve z’nin farklı değerlere sahip olduğu anlamına gelirdi. Eşitlik genellikle geçişli olduğundan, == işlemlerinin zincirlenmesi çoğu durumda doğal bir anlama sahiptir.
Stil
Doğru sözdizimine sahip olduğunuz sürece kaç öğe ve karşılaştırma işlemi kullanacağınız konusunda teorik bir sınır yoktur:
1 > -1 < 2 > 0.5 < 100 != 24
Her karşılaştırma True döndürürse yukarıdaki ifade True döndürülür. Ancak, bu şekilde zincirleme ifadeler kullanmak iyi bir stil değildir. İyi bir zincirlemenin “yönü” olması daha iyi olur:
1 > x > -4 > y != 8
Yan etkiler
Karşılaştırmalardan biri False sonucunu verir vermez, ifade hemen False olarak değerlendirilir ve kalan tüm karşılaştırmalar atlanır (tembel karşılaştırma).
a > exp > b durumundaki exp ifadesinin yalnızca bir kez değerlendirileceğini, oysa
a > exp and exp > b
ifadesinde ise exp’in iki kez değerlendirileceğini unutmayın.
is ile karşılaştırma
Yaygın bir yanlışlık, eşitlik karşılaştırma operatörleri is ve ==’nin karıştırılmasıdır.
a == b, a ve b değerlerini karşılaştırır.
a is b, a ve b’nin özdeşliklerini karşılaştırır.
Örnek vermek gerekirse:
a = 'Python eğlencelidir!'
b = 'Python eğlencelidir!'
a == b # True döndürür
a is b # False döndürür
a = [1, 2, 3, 4, 5]
b = a # b a'ya referans verir
a == b # Doğru
a is b # Doğru
b = a[:] # b şimdi a'nın bir kopyasına başvurur
a == b # Doğru
a is b # False [!!!]
Temel olarak is, id(a) == id(b) ifadesinin kısaltması olarak düşünülebilir.
Bunun ötesinde, çalışma anında işlerin daha da karmaşıklaştığı tuhaflıklar da bulunabilir. Python aynı nesneler için daha az bellek kullanmaya çalıştığından, kısa dizeler ve küçük tamsayılar is ile karşılaştırıldığında True dönecektir.
a = 'kısa'
b = 'kısa'
c = 5
d = 5
a is b # Doğru
c is d # Doğru
Ancak daha uzun dizeler ve daha büyük tamsayılar ayrı olarak saklanacaktır.
a = 'çok kısa değil'
b = 'çok kısa değil'
c = 1000
d = 1000
a is b # False
c is d # False
None’ı test etmek için de is kullanmalısınız:
if myvar is not None:
# None değil
pass
if myvar is None:
# None
pass
is‘in bir kullanımı da “sentinel” (benzersiz bir nesne) test etmek için olabilir.
sentinel = object()
def myfunc(var=sentinel):
if var is sentinel:
# değer verilmedi
pass
else:
# değer verildi
pass
Daha büyük veya daha küçük karşılaştırması
x > y
x < y
Bu operatörler iki tür değeri karşılaştırır, bunlar küçüktür ve büyüktür operatörleridir. Sayılar için, basitçe, hangisinin daha büyük olduğunu görmek için sayısal değerleri karşılaştırır:
12 > 4 # Doğru
12 < 4 # Yanlış
1 < 4 # Doğru
Dizeler için, alfabetik sıraya benzeyen ancak tam olarak aynı olmayan leksikografik olarak karşılaştırırlar.
“alpha” < “beta” # Doğru
“gamma” > “beta” # Doğru
“gamma” < “OMEGA” # Yanlış
Bu karşılaştırmalarda, küçük harfler büyük harflerden ‘büyük’ olarak kabul edilir, bu nedenle “gamma” < “OMEGA” yanlıştır. Hepsi büyük harf olsaydı, beklenen alfabetik sıralama sonucunu döndürürdü:
“GAMMA” < “OMEGA” # Doğru
Her tür < ve > operatörleriyle hesaplamayı farklı şekilde tanımlar, bu nedenle kullanmadan önce operatörlerin belirli bir türle ne anlama geldiğini araştırmalısınız.
Eşit değil karşılaştırması
x != y
Bu ifade x ve y eşit değilse True döndürür, aksi takdirde False döndürür.
Eşittir karşılaştırması
x == y
Bu ifade, x ve y değerlerinin aynı olup olmadığını değerlendirir ve sonucu boolean değeri olarak döndürür. Genellikle hem türün hem de değerin eşleşmesi gerekir, bu nedenle int 12, ’12’ dizesiyle aynı değildir.
12 == 12 # Doğru
12 == 1 # Yanlış
’12’ == ’12’ #Doğru
‘spam’ == ‘spam’ # Doğru
‘spam’ == ‘spam’ # Yanlış
’12’ == 12 # Yanlış
Her türün, iki değerin aynı olup olmadığını değerlendirmek için kullanılacak bir işlev tanımlaması gerektiğini unutmayın. Yerleşik türler için bu fonksiyonlar beklediğiniz gibi davranır ve sadece aynı değer olma durumuna göre değerlendirme yapar. Ancak özel tipler, eşitlik testini her zaman True veya her zaman False döndürmek de dahil olmak üzere istedikleri şekilde tanımlayabilirler.
Nesneleri Karşılaştırma
Özel sınıfların eşitliğini karşılaştırmak için, __eq__ ve ___ne__ yöntemlerini tanımlayarak == ve != değerlerini geçersiz kılabilirsiniz. Ayrıca __lt__ (<), __le__ (<=), __gt__ (>) ve __ge__ (>) yöntemlerini de geçersiz kılabilirsiniz. Yalnızca iki karşılaştırma yöntemini geçersiz kılmanız gerektiğini ve Python’un geri kalanını halledebileceğini unutmayın (==, not < ve not > ile aynıdır, vb.)
class Foo(object):
def __init__(self, item):
self.my_item = item
def __eq__(self, other):
return self.my_item == other.my_item
a = Foo(5)
b = Foo(5)
a == b # True
a != b # False
a is b # False
Bu basit karşılaştırmanın, diğerinin (karşılaştırılan nesne) aynı nesne türü olduğunu varsaydığını unutmayın. Başka bir türle karşılaştırma hata verecektir:
class Bar(object):
def __init__(self, item):
self.other_item = item
def __eq__(self, other):
return self.other_item == other.other_item
def __ne__(self, other):
return self.other_item != other.other_item
c = Bar(5)
a == c # AttributeError: 'Foo' object has no attribute 'other_item'
isinstance() veya benzer bir kontrol bunu önlemeye yardımcı olacaktır (eğer istenirse).