if-elif-else Yapısı
Programlama dünyasında karar vermek her şeydir. Düşün: sabah kalktığında "hava yağmurlu mu?" diye sorarsın — cevaba göre şemsiye alırsın ya da almazsın. İşte Python'da if, elif ve else tam olarak bunu yapar. Programına "şu koşul sağlanıyorsa şunu yap, değilse bunu yap" deme gücü verir.
Bu ders, Python'daki koşullu ifadelerin tüm detaylarını kapsıyor. Basit if bloklarından başlayıp, match-case gibi modern yapılara kadar gideceğiz. Hazırsan, başlayalım!
if Nedir? Temel Söz Dizimi
if ifadesi, bir koşulun doğru (True) olup olmadığını kontrol eder. Koşul doğruysa altındaki kod bloğu çalışır, değilse atlanır. Bu kadar basit.
sicaklik = 35
if sicaklik > 30:
print("Hava çok sıcak, bol su iç!")Burada sicaklik > 30 bir boolean ifade — yani sonucu ya True ya da False. Değer 35 olduğu için koşul True döner ve print çalışır.
Söz dizimi kuralları çok net:
ifanahtar kelimesiKoşul ifadesi
İki nokta üst üste
:Alt satırda girintili (indented) kod bloğu
else: "Değilse" Durumu
Bazen sadece "koşul sağlanıyorsa yap" yetmez. "Sağlanmıyorsa da şunu yap" demek istersin. İşte else budur.
yas = 16
if yas >= 18:
print("Ehliyet alabilirsin.")
else:
print("Ehliyet için biraz daha beklemelisin.")else bloğu, if koşulu False olduğunda çalışır. Dikkat et: else kendi başına bir koşul almaz. Sadece "yukarıdaki hiçbir koşul tutmadıysa" anlamına gelir.
Bir analoji yapayım: if-else yapısı bir yol ayrımına benzer. Yolun ikiye ayrıldığı noktadasın — ya sola gidersin ya sağa. Üçüncü bir seçenek yok (en azından şimdilik).
elif: Birden Fazla Koşul
Gerçek hayatta seçenekler genellikle ikiden fazladır. "Not 90'dan büyükse AA, 80'den büyükse BA, 70'den büyükse BB..." gibi. İşte elif (else if'in kısaltması) bu çoklu dallanmayı sağlar.
not_ortalamasi = 78
if not_ortalamasi >= 90:
harf = "AA"
elif not_ortalamasi >= 80:
harf = "BA"
elif not_ortalamasi >= 70:
harf = "BB"
elif not_ortalamasi >= 60:
harf = "CB"
else:
harf = "FF"
print(f"Harf notun: {harf}") # Harf notun: BBBurada önemli bir detay var: Python koşulları yukarıdan aşağıya sırayla kontrol eder. İlk True olan koşulun bloğu çalışır ve geri kalanlar atlanır. Bu yüzden sıralama önemli!
Mesela not_ortalamasi 95 olsa, ilk koşul (>= 90) True olur, "AA" atanır ve alt satırlardaki elif'lere hiç bakılmaz. Bu bir kısa devre (short-circuit) davranışıdır.
elif Zinciri Ne Kadar Uzun Olabilir?
Teknik olarak sınır yok. Ama 5-6'dan fazla elif zinciri görüyorsan, muhtemelen bir dictionary mapping veya match-case kullanman daha temiz olur. Buna ileride değineceğiz.
# Uzun elif yerine dictionary yaklaşımı
gun_numarasi = 3
gunler = {
1: "Pazartesi",
2: "Salı",
3: "Çarşamba",
4: "Perşembe",
5: "Cuma",
6: "Cumartesi",
7: "Pazar"
}
gun_adi = gunler.get(gun_numarasi, "Geçersiz gün")
print(gun_adi) # ÇarşambaIndentation: Python'un Kalp Atışı
Python'da girintileme (indentation) sadece estetik değil, söz diziminin bir parçası. Diğer dillerde süslü parantezler {} blokları belirlerken, Python'da girintiler belirler.
# ✅ Doğru
if True:
print("Bu çalışır")
print("Bu da çalışır")
# ❌ Yanlış — IndentationError
if True:
print("Bu hata verir!")Standart kural: 4 boşluk (space) kullan. Tab da çalışır ama tab ile space'i karıştırma — Python 3'te bu doğrudan TabError verir.
# ❌ Tab ve space karışımı — TabError!
if True:
print("space ile") # 4 space
print("tab ile") # 1 tab — HATA!💡 İpucu: Modern editörlerin (VS Code, PyCharm) hepsi tab tuşuna bastığında otomatik 4 space ekler. Bu ayarı kontrol et ve "Insert Spaces" modunda olduğundan emin ol.
Bir blok içindeki tüm satırlar aynı seviyede girintili olmalı:
if True:
print("satır 1") # 4 space
print("satır 2") # 4 space
print("satır 3") # 6 space — IndentationError!Nested if vs elif Zinciri
İç içe (nested) if blokları yazmak mümkün ama her zaman doğru seçim değil. Bakalım ne zaman hangisini kullanmalısın.
Nested if (İç İçe)
yas = 25
ehliyet_var = True
if yas >= 18:
if ehliyet_var:
print("Araba kullanabilirsin.")
else:
print("Önce ehliyet al.")
else:
print("Yaşın yetmiyor.")Burada ikinci if, birincinin içinde. Yani dıştaki koşul sağlanmadan içtekine bakılmaz bile. Bu mantıksal olarak doğru — yaşı yetmeyenin ehliyet durumunu kontrol etmenin anlamı yok.
Aynı Mantık, elif ile
yas = 25
ehliyet_var = True
if yas < 18:
print("Yaşın yetmiyor.")
elif not ehliyet_var:
print("Önce ehliyet al.")
else:
print("Araba kullanabilirsin.")Bu da aynı işi yapar ama daha düz (flat) bir yapıda. Genel kural: girintileme derinliği 2-3'ü geçiyorsa, yapıyı düzleştirmeyi düşün. Çünkü derin iç içe yapılar okunması zor "ok kodu" (arrow code) yaratır.
Arrow Code Problemi
# ❌ Arrow code — okunması zor
def islemi_yap(kullanici, siparis):
if kullanici is not None:
if kullanici.aktif:
if siparis is not None:
if siparis.toplam > 0:
if kullanici.bakiye >= siparis.toplam:
# Asıl iş burada
print("Sipariş onaylandı!")Bu koda bak — asıl iş 5 seviye girintide! Bunu guard clause pattern ile düzeltebilirsin (birazdan göreceğiz).
Ternary Expression (Üçlü İfade)
Bazı if-else blokları o kadar basittir ki tek satırda yazılabilir. Python'un ternary (üçlü) ifadesi bunu sağlar.
n = 7
# Klasik yol
if n > 0:
sonuc = "pozitif"
else:
sonuc = "negatif"
# Ternary yol
sonuc = "pozitif" if n > 0 else "negatif"
print(sonuc) # pozitifSöz dizimi: değer_true if koşul else değer_false
Bu tek satırlık ifade, özellikle değişken ataması ve return ifadelerinde çok kullanışlı:
# Değişken ataması
durum = "yetişkin" if yas >= 18 else "çocuk"
# Return ifadesinde
def mutlak_deger(n):
return n if n >= 0 else -n
# f-string içinde
print(f"Sayı {'çift' if n % 2 == 0 else 'tek'}")İç İçe Ternary (Kaçının!)
Teknik olarak ternary'leri iç içe yazabilirsin ama yapma.
# ❌ Okunması zor
kategori = "A" if puan >= 90 else "B" if puan >= 70 else "C"
# ✅ Bunun yerine normal if-elif kullan
if puan >= 90:
kategori = "A"
elif puan >= 70:
kategori = "B"
else:
kategori = "C"⚠️ Dikkat: Ternary expression sadece basit, iki seçenekli durumlarda kullan. İç içe ternary yazmak kodun okunabilirliğini ciddi şekilde düşürür. "Akıllı kod" yazmak yerine "anlaşılır kod" yaz.
match-case: Python 3.10+ Structural Pattern Matching
Python 3.10 ile gelen match-case, diğer dillerdeki switch-case'e benzer ama çok daha güçlü. Sadece değer karşılaştırması değil, yapısal desen eşleştirmesi (structural pattern matching) yapabilir.
Temel Kullanım
komut = "start"
match komut:
case "start":
print("Sistem başlatılıyor...")
case "stop":
print("Sistem durduruluyor...")
case "restart":
print("Sistem yeniden başlatılıyor...")
case _:
print(f"Bilinmeyen komut: {komut}")case _: burada wildcard — hiçbir desen tutmadığında çalışır. else'in karşılığı gibi düşün.
OR Pattern (Birden Fazla Değer)
gun = "cumartesi"
match gun:
case "pazartesi" | "salı" | "çarşamba" | "perşembe" | "cuma":
print("İş günü")
case "cumartesi" | "pazar":
print("Hafta sonu!")| operatörü ile birden fazla deseni tek case'de birleştirebilirsin.
Yapısal Desen Eşleştirme
İşte match-case'in gerçek gücü buradan geliyor. Sadece değerleri değil, veri yapılarının şeklini eşleştirebilirsin.
# Tuple pattern matching
nokta = (3, 0)
match nokta:
case (0, 0):
print("Orijin noktası")
case (x, 0):
print(f"X ekseninde, x={x}")
case (0, y):
print(f"Y ekseninde, y={y}")
case (x, y):
print(f"Genel nokta: ({x}, {y})")Burada x ve y değişkenleri otomatik olarak bağlanıyor (binding). (3, 0) değeri (x, 0) deseniyle eşleşir ve x otomatik olarak 3 olur. Bu, basit switch-case'in çok ötesinde bir özellik.
Guard (Koşullu Case)
yas = 25
match yas:
case n if n < 0:
print("Geçersiz yaş")
case n if n < 18:
print("Çocuk")
case n if n < 65:
print("Yetişkin")
case _:
print("Emekli")if ile case'e ek koşul ekleyebilirsin. Buna guard denir.
Dict / Mapping Pattern
event = {"type": "click", "x": 100, "y": 200}
match event:
case {"type": "click", "x": x, "y": y}:
print(f"Tıklama: ({x}, {y})")
case {"type": "keypress", "key": k}:
print(f"Tuş basıldı: {k}")
case _:
print("Bilinmeyen event")Dictionary'lerin yapısını eşleştirebilirsin — bu özellikle API response'ları veya event handling için harika.
💡 İpucu:
match-casePython 3.10+ gerektirir. Eğer 3.9 veya altı kullanıyorsan,if-elifzinciri veya dictionary mapping kullanmaya devam et. Projenin minimum Python versiyonunu kontrol etmeyi unutma!
Truthy ve Falsy Değerler
Python'da her değer bir boolean bağlamında ya True (truthy) ya da False (falsy) olarak değerlendirilir. Bu, if ifadelerini çok daha kısa yazmana olanak tanır.
Falsy Değerler (False olarak değerlendirilen)
# Bunların hepsi False olarak değerlendirilir:
falsy_degerler = [
False, # Boolean False
None, # None
0, # Sıfır (int)
0.0, # Sıfır (float)
0j, # Sıfır (complex)
"", # Boş string
[], # Boş liste
{}, # Boş dictionary
set(), # Boş set
(), # Boş tuple
range(0), # Boş range
]
for deger in falsy_degerler:
print(f"{str(deger):12} -> bool: {bool(deger)}")Bunlar dışındaki her şey truthy'dir. "False" string'i bile truthy'dir (boş olmayan string olduğu için)!
Kısa if Kalıpları
Bu bilgiyi kullanarak daha Pythonic kod yazabilirsin:
isimler = ["Ahmet", "Mehmet", "Ayşe"]
# ❌ Gereksiz uzun
if len(isimler) > 0:
print("Liste dolu")
# ✅ Pythonic
if isimler:
print("Liste dolu")
# ❌ Gereksiz uzun
if isim != "":
print("İsim var")
# ✅ Pythonic
if isim:
print("İsim var")Aynı şekilde boşluk kontrolü:
sonuc = None
# ❌ Gereksiz uzun
if sonuc is not None:
print(sonuc)
# ✅ Pythonic (çoğu durumda)
if sonuc:
print(sonuc)Ama Dikkatli Ol!
Truthy/falsy ile kısa if her zaman doğru değildir:
puan = 0
# ⚠️ Tehlikeli! 0 geçerli bir puan olabilir
if puan: # 0 falsy olduğu için False döner
print(f"Puan: {puan}")
else:
print("Puan girilmemiş") # Yanlış!
# ✅ Doğru yaklaşım
if puan is not None:
print(f"Puan: {puan}")0 geçerli bir değerse, if puan: kullanmak hatalı olur çünkü 0 falsy'dir. Bu durumda is not None kontrolü daha doğru.
Guard Clause Pattern (Erken Çıkış)
Guard clause, fonksiyonun başında geçersiz durumları eleyip erken çıkış (early return) yapma tekniğidir. Bu, iç içe if bloklarını düzleştirir ve kodun okunabilirliğini dramatik şekilde artırır.
Problemi Görelim
# ❌ Arrow code — derin iç içe yapı
def siparis_onayla(kullanici, urun, adet):
if kullanici is not None:
if kullanici.aktif:
if urun is not None:
if urun.stok >= adet:
if kullanici.bakiye >= urun.fiyat * adet:
# Asıl iş
kullanici.bakiye -= urun.fiyat * adet
urun.stok -= adet
return "Sipariş onaylandı!"
else:
return "Yetersiz bakiye"
else:
return "Stok yetersiz"
else:
return "Ürün bulunamadı"
else:
return "Hesap aktif değil"
else:
return "Kullanıcı bulunamadı"Bu kodu okumak gerçekten zor. else blokları hangi if'e ait, takip etmek kabus gibi.
Guard Clause ile Çözüm
# ✅ Guard clause — düz ve okunabilir
def siparis_onayla(kullanici, urun, adet):
if kullanici is None:
return "Kullanıcı bulunamadı"
if not kullanici.aktif:
return "Hesap aktif değil"
if urun is None:
return "Ürün bulunamadı"
if urun.stok < adet:
return "Stok yetersiz"
if kullanici.bakiye < urun.fiyat * adet:
return "Yetersiz bakiye"
# Tüm kontroller geçti — asıl iş
kullanici.bakiye -= urun.fiyat * adet
urun.stok -= adet
return "Sipariş onaylandı!"Farkı gör: hiç iç içe yapı yok. Her kontrol bağımsız, sırayla yapılıyor. Bir koşul başarısız olursa fonksiyon hemen çıkıyor. Asıl iş mantığı en altta, hiç girintisiz.
Guard clause pattern'ının güzelliği, kapı görevlisi (bouncer) analojisiyle anlaşılır: Gece kulübünün kapısındaki görevli gibi düşün. Önce yaşını kontrol eder — uygun değilse geri çevirir. Sonra kıyafetini kontrol eder — uygun değilse geri çevirir. Her şey uygunsa içeri alır. Her kontrolde "geçemezsen git" mantığı var.
Guard Clause Ne Zaman Kullanılır?
Parametre doğrulama (validation): Fonksiyonun başında geçersiz girdileri ele
Hata durumları: Erken return ile hata mesajı döndürme
Ön koşullar: İşleme devam etmek için gereken minimum koşullar
def dosya_oku(dosya_yolu):
if not dosya_yolu:
return None
if not dosya_yolu.endswith(".txt"):
raise ValueError("Sadece .txt dosyaları desteklenir")
# Guard'lar geçildi, asıl okuma işlemi
with open(dosya_yolu, "r") as f:
return f.read()Karşılaştırma ve Mantıksal Operatörler
if ifadelerinde sıkça kullanılan operatörleri hızlıca hatırlayalım.
Karşılaştırma Operatörleri
a, b = 5, 10
print(a == b) # False — eşit mi?
print(a != b) # True — eşit değil mi?
print(a > b) # False — büyük mü?
print(a < b) # True — küçük mü?
print(a >= b) # False — büyük eşit mi?
print(a <= b) # True — küçük eşit mi?Mantıksal Operatörler: and, or, not
yas = 25
gelir = 5000
# and: İki koşul da True olmalı
if yas >= 18 and gelir >= 3000:
print("Kredi başvurusu yapabilir")
# or: En az biri True olmalı
if yas < 18 or gelir < 1000:
print("Kredi başvurusu reddedildi")
# not: Koşulu tersine çevirir
is_banned = False
if not is_banned:
print("Giriş yapabilir")Zincirleme Karşılaştırma (Chained Comparison)
Python'a özel güzel bir özellik:
yas = 25
# ❌ Diğer dillerdeki gibi
if yas >= 18 and yas <= 65:
print("Çalışma yaşında")
# ✅ Python'a özel — matematik notasyonu gibi
if 18 <= yas <= 65:
print("Çalışma yaşında")
# Birden fazla zincirleme
x = 5
if 0 < x < 10 < 100: # 0 < 5 and 5 < 10 and 10 < 100
print("Hepsi True")Bu, matematikteki 18 ≤ yaş ≤ 65 notasyonunun birebir Python karşılığı. Çoğu dilde bu mümkün değil!
is vs ==
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — değerleri aynı
print(a is b) # False — farklı nesneler
print(a is c) # True — aynı nesne
# None kontrolünde her zaman is kullan
x = None
if x is None: # ✅ Doğru
print("x None")
if x == None: # ❌ Çalışır ama tavsiye edilmez
print("x None")== değer eşitliği, is kimlik eşitliği (aynı nesne mi?) kontrol eder. None, True, False kontrollerinde her zaman is kullan.
Short-Circuit Evaluation (Kısa Devre)
Python, mantıksal operatörlerde kısa devre değerlendirmesi yapar:
# and: İlk False'ta durur
def pahalı_fonksiyon():
print("Çalıştım!")
return True
# koşul1 False ise pahalı_fonksiyon hiç çağrılmaz
koşul1 = False
if koşul1 and pahalı_fonksiyon():
print("İkisi de True")
# pahalı_fonksiyon çağrılmadı — performans kazancı!
# or: İlk True'da durur
koşul2 = True
if koşul2 or pahalı_fonksiyon():
print("En az biri True")
# Yine pahalı_fonksiyon çağrılmadıBu davranış, guard clause pattern'ını güvenli yapar:
# items None olsa bile hata vermez
if items is not None and len(items) > 0:
print(items[0])
# Çünkü items None ise, len(items) hiç çağrılmazPratik Örnekler
Örnek 1: Basit Giriş Sistemi
kullanici_adi = "admin"
sifre = "12345"
girilen_kullanici = input("Kullanıcı adı: ")
girilen_sifre = input("Şifre: ")
if girilen_kullanici == kullanici_adi and girilen_sifre == sifre:
print("Giriş başarılı! Hoş geldiniz.")
elif girilen_kullanici != kullanici_adi:
print("Kullanıcı adı hatalı.")
else:
print("Şifre hatalı.")Örnek 2: Vergi Hesaplama (Dilim Sistemi)
gelir = 150000
if gelir <= 32000:
vergi = gelir * 0.15
elif gelir <= 70000:
vergi = 32000 * 0.15 + (gelir - 32000) * 0.20
elif gelir <= 170000:
vergi = 32000 * 0.15 + 38000 * 0.20 + (gelir - 70000) * 0.27
elif gelir <= 880000:
vergi = 32000 * 0.15 + 38000 * 0.20 + 100000 * 0.27 + (gelir - 170000) * 0.35
else:
vergi = 32000 * 0.15 + 38000 * 0.20 + 100000 * 0.27 + 710000 * 0.35 + (gelir - 880000) * 0.40
print(f"Gelir: {gelir:,.0f} TL")
print(f"Vergi: {vergi:,.0f} TL")Örnek 3: match-case ile Hesap Makinesi
sayi1 = float(input("Birinci sayı: "))
islem = input("İşlem (+, -, *, /): ")
sayi2 = float(input("İkinci sayı: "))
match islem:
case "+":
sonuc = sayi1 + sayi2
case "-":
sonuc = sayi1 - sayi2
case "*":
sonuc = sayi1 * sayi2
case "/":
if sayi2 == 0:
print("Sıfıra bölme hatası!")
sonuc = None
else:
sonuc = sayi1 / sayi2
case _:
print(f"Geçersiz işlem: {islem}")
sonuc = None
if sonuc is not None:
print(f"{sayi1} {islem} {sayi2} = {sonuc}")Yaygın Hatalar ve Anti-Pattern'ler
1. Boolean ile Gereksiz Karşılaştırma
is_active = True
# ❌ Gereksiz
if is_active == True:
print("Aktif")
# ✅ Pythonic
if is_active:
print("Aktif")
# ❌ Gereksiz
if is_active == False:
print("Pasif")
# ✅ Pythonic
if not is_active:
print("Pasif")2. Birden Fazla return Yerine Değişken Kullanma
# ❌ Gereksiz değişken
def kontrol(x):
sonuc = False
if x > 0:
sonuc = True
return sonuc
# ✅ Direkt return
def kontrol(x):
return x > 03. Aynı Değişkeni Tekrar Tekrar Kontrol Etme
renk = "kırmızı"
# ❌ Tekrarlı
if renk == "kırmızı" or renk == "mavi" or renk == "yeşil":
print("Geçerli renk")
# ✅ in operatörü ile
if renk in ("kırmızı", "mavi", "yeşil"):
print("Geçerli renk")4. Mutable Default ve if Kontrolü
# ❌ Tehlikeli
def ekle(item, liste=[]):
liste.append(item)
return liste
# ✅ Güvenli
def ekle(item, liste=None):
if liste is None:
liste = []
liste.append(item)
return listeİleri Teknikler
Conditional Expression ile Dictionary
# Basit mapping'lerde dict kullan
STATUS_MESAJLARI = {
200: "Başarılı",
404: "Bulunamadı",
500: "Sunucu Hatası",
}
kod = 404
mesaj = STATUS_MESAJLARI.get(kod, "Bilinmeyen durum kodu")
print(mesaj) # Bulunamadıany() ve all() ile Çoklu Koşul
notlar = [85, 72, 90, 68, 95]
# Herhangi biri 90'dan büyük mü?
if any(n > 90 for n in notlar):
print("En az bir parlak öğrenci var!")
# Hepsi 60'tan büyük mü?
if all(n > 60 for n in notlar):
print("Herkes geçti!")Boolean Operatörlerin Dönüş Değeri
Python'da and ve or aslında True/False döndürmez — son değerlendirilen değeri döndürür:
# or: İlk truthy değeri döndürür
isim = "" or "Anonim"
print(isim) # "Anonim"
# and: İlk falsy değeri veya son değeri döndürür
sonuc = "Ahmet" and "Mehmet"
print(sonuc) # "Mehmet"
# Pratik kullanım: default değer atama
kullanici_ismi = girilen_isim or "Misafir"Bu özellik default değer atama için çok kullanışlı, ama dikkatli ol — 0, "", [] gibi geçerli değerler de falsy'dir.
Özet
`if-elif-else` Python'un temel karar yapısıdır. Koşullar yukarıdan aşağıya sırayla kontrol edilir; ilk True olan çalışır.
Indentation Python'da söz diziminin parçasıdır — 4 space standart, tab/space karıştırma.
Ternary expression (
x if koşul else y) basit if-else'leri tek satıra sığdırır, ama iç içe kullanma.`match-case` (Python 3.10+) sadece değer değil yapısal desen eşleştirmesi yapar — tuple, dict, class pattern'ları destekler.
Truthy/falsy bilgisi ile daha kısa if ifadeleri yazabilirsin, ama
0ve""gibi geçerli falsy değerlere dikkat et.Guard clause pattern ile derin iç içe yapıları düzleştir — fonksiyonun başında geçersiz durumları erken return ile ele.
AI Asistan
Sorularını yanıtlamaya hazır