break, continue, pass ve Döngü Teknikleri
Döngüler güçlü araçlar ama bazen "döngünün ortasında dur" ya da "bu adımı atla, sonrakine geç" demek istersin. İşte break, continue ve pass tam olarak bu kontrolü sağlayan ifadeler. Bunlar döngülerin akışını yönetmeni sağlayan kontrol düğmeleri gibi.
Bir asansör analojisi düşün: Asansör her katta durur (döngü). continue → "Bu katta inemiyorum, sonraki kata geç." break → "İniyorum, asansörden çık." pass → "Bu katta bir şey yapmıyorum ama durmaya devam et." Her birinin farklı bir görevi var ve doğru yerde kullanıldığında kodun hem okunabilirliğini hem verimliliğini artırır.
break: Döngüyü Sonlandır
break ifadesi döngüyü anında sonlandırır. Döngüdeki kalan iterasyonlar atlanır ve program döngüden sonraki satırdan devam eder.
# İlk negatif sayıyı bulunca dur
sayilar = [5, 12, 3, -7, 8, 15, -2]
for sayi in sayilar:
if sayi < 0:
print(f"İlk negatif sayı bulundu: {sayi}")
break
print(f"İşleniyor: {sayi}")
print("Döngü bitti.")Çıktı:
İşleniyor: 5
İşleniyor: 12
İşleniyor: 3
İlk negatif sayı bulundu: -7
Döngü bitti.-7'ye ulaşıldığında break çalışır, 8 ve 15 hiç işlenmez.
break Kullanım Alanları
1. Arama (Search)
ogrenciler = [
{"isim": "Ahmet", "numara": 101},
{"isim": "Ayşe", "numara": 102},
{"isim": "Mehmet", "numara": 103},
]
aranan_numara = 102
for ogrenci in ogrenciler:
if ogrenci["numara"] == aranan_numara:
print(f"Bulundu: {ogrenci['isim']}")
break2. Erken çıkış (Optimizasyon)
# Büyük veri setinde ilk eşleşmeyi bul
def ilk_cift_bul(sayilar):
for sayi in sayilar:
if sayi % 2 == 0:
return sayi # return da döngüyü sonlandırır
return None
# 1 milyon elemanlı listede 2. elemanda bulursa
# kalan 999,998 elemana bakmaz — büyük performans kazancı!3. while döngüsünde çıkış
while True:
komut = input("Komut (help/quit): ").strip().lower()
if komut == "quit":
break
elif komut == "help":
print("Kullanılabilir komutlar: help, quit")
else:
print(f"Bilinmeyen komut: {komut}")continue: Adımı Atla
continue ifadesi mevcut iterasyonun geri kalanını atlar ve döngünün bir sonraki iterasyonuna geçer. Döngü sona ermez, sadece o adım atlanır.
# Negatif sayıları atla, pozitif olanları işle
sayilar = [5, -3, 12, -7, 8, -1, 15]
for sayi in sayilar:
if sayi < 0:
continue # Bu adımı atla, sonrakine geç
print(f"İşleniyor: {sayi}")Çıktı:
İşleniyor: 5
İşleniyor: 12
İşleniyor: 8
İşleniyor: 15Negatif sayılarda continue çalışır, print satırı atlanır ve döngü sonraki elemana geçer.
continue vs if Karşılaştırması
Aynı işi if ile de yapabilirsin, ama continue bazen daha okunabilir olur:
# Yaklaşım 1: if ile (girintili blok)
for item in items:
if item.gecerli:
if item.aktif:
if item.fiyat > 0:
# Asıl işlem
islem_yap(item)
# Yaklaşım 2: continue ile (düz yapı — guard clause benzeri)
for item in items:
if not item.gecerli:
continue
if not item.aktif:
continue
if item.fiyat <= 0:
continue
# Asıl işlem — girintisiz!
islem_yap(item)İkinci yaklaşım guard clause pattern'ının döngü versiyonu. Geçersiz durumları erken atlayarak asıl işlemi düz tutarsın.
continue Kullanım Alanları
1. Filtre pattern'ı
# Hatalı verileri atla
veriler = ["42", "merhaba", "17", "", "99", "abc", "0"]
gecerli_sayilar = []
for veri in veriler:
if not veri:
continue
try:
sayi = int(veri)
except ValueError:
continue
gecerli_sayilar.append(sayi)
print(gecerli_sayilar) # [42, 17, 99, 0]2. Log kayıtlarını filtreleme
log_satirlari = [
"[INFO] Sistem başlatıldı",
"[DEBUG] Bağlantı kontrolü",
"[ERROR] Veritabanı hatası!",
"[DEBUG] Sorgu çalıştırıldı",
"[ERROR] Timeout hatası!",
"[INFO] İşlem tamamlandı",
]
print("Sadece hatalar:")
for satir in log_satirlari:
if "[ERROR]" not in satir:
continue
print(satir)3. while döngüsünde continue
# while'da continue: koşul kontrolü başa döner
i = 0
while i < 10:
i += 1
if i % 3 == 0:
continue # 3'e bölünenleri atla
print(i, end=" ")
# 1 2 4 5 7 8 10⚠️ Dikkat: while döngüsünde
continuekullanırken dikkat! Eğer sayaç artırmacontinue'dan sonra yapılıyorsa sonsuz döngüye girersin:
>
``
python i = 0 while i < 10: if i == 5: continue # i artırılmadan başa döner → sonsuz döngü! print(i) i += 1``
>
Çözüm: Sayacı her zaman
continue'dan önce artır!
pass: Yer Tutucu (Placeholder)
pass ifadesi hiçbir şey yapmaz. Söz dizimi bir blok gerektirdiğinde ama henüz kod yazmak istemediğinde kullanılır.
# Henüz implemente edilmemiş fonksiyon
def gelecekte_yazilacak_fonksiyon():
pass
# Boş class
class GelecekteYazilacakClass:
pass
# Boş if bloğu
x = 10
if x > 5:
pass # TODO: Burayı sonra doldur
else:
print("x küçük")
# Boş except bloğu (hatayı sessizce geç)
try:
sonuc = 10 / 0
except ZeroDivisionError:
pass # Hatayı yut (genellikle kötü pratik!)pass vs continue
Bu ikisi karıştırılabilir ama çok farklılar:
for i in range(5):
if i == 3:
pass # Hiçbir şey yapmaz ama ALTTAKİ KOD ÇALIŞIR
print(i)
# 0, 1, 2, 3, 4 — hepsi yazdırılır!
for i in range(5):
if i == 3:
continue # Bu adımı ATLAR, alttaki kod çalışmaz
print(i)
# 0, 1, 2, 4 — 3 atlandı!pass: "Burada bir şey yapmayacağım ama devam et." continue: "Bu iterasyonun geri kalanını atla."
pass Yerine Alternatifler
# Ellipsis (...) — özellikle type hinting ve abstract methodlarda
def henuz_yazilmadi():
...
# Veya açıklayıcı bir hata fırlat
def henuz_yazilmadi():
raise NotImplementedError("Bu fonksiyon henüz yazılmadı")💡 İpucu:
passkullanırken yanına bir# TODOyorumu ekle. Bu sayede neden boş olduğunu ve ne zaman dolduracağını hatırlarsın. IDE'ler de TODO yorumlarını takip edebilir.
for-else ve while-else Detaylı
else bloğunun döngülerle kullanımını daha önce gördük ama burada break ile ilişkisini derinleştirelim.
Temel Kural
`else` bloğu, döngü `break` ile kesilMEDEN tamamlandığında çalışır.
# break ÇALIŞIRSA → else ÇALIŞMAZ
for i in range(5):
if i == 3:
break
else:
print("Bu yazdırılMAZ")
# break ÇALIŞMAZSA → else ÇALIŞIR
for i in range(5):
if i == 10: # Hiçbir zaman True olmaz
break
else:
print("Bu yazdırılır!")Pratik Senaryo: Parola Doğrulama
DOGRU_SIFRE = "python123"
MAX_DENEME = 3
for deneme in range(1, MAX_DENEME + 1):
sifre = input(f"Şifre ({deneme}/{MAX_DENEME}): ")
if sifre == DOGRU_SIFRE:
print("✅ Giriş başarılı!")
break
else:
# 3 denemede de doğru şifre girilmedi
print("🔒 Hesap kilitlendi!")while-else Örneği
import random
hedef = random.randint(1, 10)
kalan = 3
while kalan > 0:
tahmin = int(input(f"Tahmin (1-10, {kalan} hak): "))
if tahmin == hedef:
print("🎉 Bildin!")
break
kalan -= 1
if kalan > 0:
ipucu = "📈 Daha büyük" if tahmin < hedef else "📉 Daha küçük"
print(ipucu)
else:
print(f"😞 Bulamadın! Cevap: {hedef}")else Olmadan Aynı Mantık
for-else'i kullanmak istemiyorsan flag değişkeni ile aynı işi yapabilirsin:
# for-else versiyonu
for item in koleksiyon:
if kosul(item):
islem_yap(item)
break
else:
bulunamadi_islemi()
# Flag versiyonu (aynı mantık)
bulundu = False
for item in koleksiyon:
if kosul(item):
islem_yap(item)
bulundu = True
break
if not bulundu:
bulunamadi_islemi()İkisi de çalışır. Hangisini tercih edeceğin ekibe ve kişisel tercihe bağlı.
Label Yok! Nested Loop'tan Çıkış Teknikleri
Java, C gibi dillerde döngülere etiket (label) koyup break outer; diyebilirsin. Python'da label mekanizması yoktur. İç içe döngüden çıkmak biraz farklı teknikler gerektirir.
Problem
# İç döngüde break, sadece iç döngüyü kırar!
for i in range(5):
for j in range(5):
if i * j > 6:
break # Sadece iç for'u kırar, dış devam eder!
print(f"({i},{j})", end=" ")
print()Çözüm 1: Flag Değişkeni
cikis = False
for i in range(5):
for j in range(5):
if i * j > 6:
cikis = True
break
print(f"({i},{j})", end=" ")
if cikis:
break
print()
print("\nDöngüden çıkıldı.")Çalışır ama çirkin. Her iç içe katman için flag kontrolü eklemen gerekir.
Çözüm 2: Fonksiyona Çıkarma (En Temiz!)
def matris_ara(matris, hedef):
for i, satir in enumerate(matris):
for j, eleman in enumerate(satir):
if eleman == hedef:
return (i, j) # return tüm fonksiyondan çıkar
return None # Bulunamadı
matris = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
sonuc = matris_ara(matris, 5)
print(f"Bulundu: {sonuc}") # (1, 1)Fonksiyon içindeki return tüm iç döngülerden anında çıkar. Bu en temiz ve en önerilen yöntemdir.
Çözüm 3: Exception Kullanma (Aşırı Durumlar İçin)
class DonguCikis(Exception):
pass
try:
for i in range(10):
for j in range(10):
for k in range(10):
if i + j + k > 15:
raise DonguCikis()
print(f"({i},{j},{k})", end=" ")
except DonguCikis:
print("\nÜç katmanlı döngüden çıkıldı!")Bu yöntem çalışır ama genellikle overkill'dir. Sadece gerçekten karmaşık durumlarda ve fonksiyona çıkarmanın mümkün olmadığı yerlerde düşün.
Çözüm 4: itertools.product ile Düzleştirme
from itertools import product
# İç içe döngü yerine tek döngü
for i, j in product(range(5), range(5)):
if i * j > 6:
break # Artık tek döngü olduğu için break çalışır!
print(f"({i},{j})", end=" ")Bu yöntemde dikkatli ol: break sadece i * j > 6 olan ilk kombinasyonda durur, sonrakileri de atlar. Davranışı iç içe döngüdeki break'ten farklı olabilir.
Walrus Operator (:=) Döngülerde
Python 3.8'de gelen walrus operator (:=), döngülerde hesaplama + kontrol birleştirmesi için çok kullanışlı.
while ile Klasik Kullanım
# ❌ Tekrarlı kod
line = input("Komut: ")
while line != "quit":
print(f"İşleniyor: {line}")
line = input("Komut: ")
# ✅ Walrus ile — DRY (Don't Repeat Yourself)
while (line := input("Komut: ")) != "quit":
print(f"İşleniyor: {line}")Walrus operator line := input("Komut: ") ifadesi hem input() sonucunu line'a atar, hem de != "quit" karşılaştırmasında kullanır. İki satır tek satıra iner.
Dosya Okumada
# Dosyayı chunk'lar halinde oku
with open("buyuk_dosya.bin", "rb") as f:
while (chunk := f.read(8192)):
islem_yap(chunk)Her turda 8KB okur, dosya bitince f.read() boş bytes döndürür (falsy), döngü biter.
Regex ile
import re
metin = "Fiyat: 42.50 TL, İndirimli: 35.00 TL, KDV: 6.30 TL"
pattern = re.compile(r"\d+\.\d+")
pos = 0
while (match := pattern.search(metin, pos)):
print(f"Bulundu: {match.group()} (pozisyon: {match.start()})")
pos = match.end()List Comprehension'da Walrus
import math
sayilar = [16, -4, 25, 0, 9, -1, 36]
# Karekökü hesapla VE 4'ten büyük olanları filtrele
sonuclar = [
kok
for sayi in sayilar
if sayi >= 0
if (kok := math.sqrt(sayi)) > 4
]
print(sonuclar) # [5.0, 6.0]itertools ile Döngü Alternatifleri
Python'un itertools modülü, döngülerle yapılan birçok işlemi daha zarif ve verimli hale getirir. Tam bir ders konusu olacak kadar geniş ama burada döngüyle ilgili temel araçlara bakalım.
takewhile ve dropwhile
from itertools import takewhile, dropwhile
veriler = [2, 4, 6, 1, 3, 5, 8]
# Koşul True oldukça al, ilk False'ta dur
bastakiler = list(takewhile(lambda x: x % 2 == 0, veriler))
print(bastakiler) # [2, 4, 6]
# Koşul True oldukça atla, ilk False'tan itibaren al
sonrakiler = list(dropwhile(lambda x: x % 2 == 0, veriler))
print(sonrakiler) # [1, 3, 5, 8]accumulate
from itertools import accumulate
sayilar = [1, 2, 3, 4, 5]
# Kümülatif toplam
kumulatif = list(accumulate(sayilar))
print(kumulatif) # [1, 3, 6, 10, 15]
# Kümülatif çarpım
import operator
kumulatif_carpim = list(accumulate(sayilar, operator.mul))
print(kumulatif_carpim) # [1, 2, 6, 24, 120]groupby
from itertools import groupby
# DİKKAT: groupby sıralı veri bekler!
ogrenciler = [
{"isim": "Ahmet", "sinif": "A"},
{"isim": "Ayşe", "sinif": "A"},
{"isim": "Mehmet", "sinif": "B"},
{"isim": "Fatma", "sinif": "B"},
{"isim": "Ali", "sinif": "B"},
]
for sinif, grup in groupby(ogrenciler, key=lambda x: x["sinif"]):
ogrenci_listesi = list(grup)
print(f"Sınıf {sinif}: {len(ogrenci_listesi)} öğrenci")
for ogr in ogrenci_listesi:
print(f" - {ogr['isim']}")chain.from_iterable
from itertools import chain
# İç içe listeyi düzleştir (flatten)
matris = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
duz_liste = list(chain.from_iterable(matris))
print(duz_liste) # [1, 2, 3, 4, 5, 6, 7, 8, 9]starmap
from itertools import starmap
# Tuple'lardaki argümanları fonksiyona aç
ciftler = [(2, 3), (4, 5), (6, 7)]
# ❌ Normal map — lambda gerekir
sonuc = list(map(lambda x: x[0] * x[1], ciftler))
# ✅ starmap — otomatik unpack
sonuc = list(starmap(lambda a, b: a * b, ciftler))
print(sonuc) # [6, 20, 42]💡 İpucu:
itertoolsfonksiyonları lazy iterator döndürür — tüm sonuçları bellekte tutmaz. Büyük veri setlerinde bu çok önemli bir avantaj.list()ile sarmalamak sadece sonucu görmek istediğinde gerekli.
Karşılaştırma Tablosu
| İfade | Ne Yapar | Nerede Kullanılır |
|---|---|---|
break | Döngüyü tamamen sonlandırır | for, while |
continue | Mevcut adımı atlar, sonrakine geçer | for, while |
pass | Hiçbir şey yapmaz (placeholder) | Her yerde |
return | Fonksiyondan çıkar (döngüyü de sonlandırır) | Fonksiyon içi |
raise | Hata fırlatır (döngüyü de sonlandırır) | Her yerde |
Ne Zaman Hangisi?
# break: Aradığını buldun, aramayı bırak
for urun in urunler:
if urun.stok > 0:
break
# continue: Bu eleman istenmeyen, atla
for urun in urunler:
if urun.fiyat <= 0:
continue
sepete_ekle(urun)
# pass: Henüz kod yazmadın, placeholder
for urun in urunler:
if urun.indirimli:
pass # TODO: indirim hesapla
else:
normal_fiyat_goster(urun)Pratik Örnekler
Örnek 1: İlk N Asal Sayı
def ilk_n_asal(n):
asallar = []
sayi = 2
while len(asallar) < n:
for i in range(2, int(sayi ** 0.5) + 1):
if sayi % i == 0:
break
else:
asallar.append(sayi)
sayi += 1
return asallar
print(ilk_n_asal(10))
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]Burada for-else ve break mükemmel bir kombinasyonda: bir bölen bulanırsa break ile çıkılır, bulunamazsa else bloğu çalışarak sayı asal listesine eklenir.
Örnek 2: Metin Ayrıştırma
metin = "isim=Ahmet, yas=25, sehir=Istanbul, aktif=true"
bilgiler = {}
for cift in metin.split(", "):
if "=" not in cift:
continue # Geçersiz format, atla
anahtar, deger = cift.split("=", 1)
bilgiler[anahtar.strip()] = deger.strip()
print(bilgiler)
# {'isim': 'Ahmet', 'yas': '25', 'sehir': 'Istanbul', 'aktif': 'true'}Yaygın Hatalar
1. break/continue'yu if İçinde Kullanmaya Çalışmak
# ❌ Bu çalışmaz — break/continue sadece döngü içinde geçerli
if True:
break # SyntaxError: 'break' outside loop2. while + continue'da Sayaç Problemi
# ❌ Sonsuz döngü!
i = 0
while i < 5:
if i == 3:
continue # i artırılmadan başa döner
print(i)
i += 1
# ✅ Sayacı continue'dan önce artır
i = 0
while i < 5:
if i == 3:
i += 1 # Önce artır!
continue
print(i)
i += 13. for-else'i Yanlış Anlama
# Yaygın yanılgı: "else, for döngüsü bittikten sonra her zaman çalışır"
# Doğrusu: "else, break OLMAZSA çalışır"
for i in range(5):
print(i)
else:
print("Bu her zaman çalışır çünkü break yok")
for i in range(5):
if i == 3:
break
else:
print("Bu ÇALIŞMAZ çünkü break var")Özet
`break` döngüyü tamamen sonlandırır — arama, erken çıkış ve optimizasyon senaryolarında kullan.
`continue` mevcut adımı atlayıp sonrakine geçer — filtreleme ve geçersiz veri atlama senaryolarında guard clause tarzında kullan.
`pass` hiçbir şey yapmaz, söz diziminin blok gerektirdiği yerlerde placeholder olarak kullan — yanına
# TODOyorumu ekle.`for-else` / `while-else` döngü
breakolmadan tamamlandığında else çalışır — "ara, bulamazsan şunu yap" kalıbı.Nested loop'tan çıkış için Python'da label yok — en temiz çözüm fonksiyona çıkarmak (
returnkullanmak).Walrus operator (`:=`) döngülerde atama + kontrol birleştirmesi sağlar — özellikle
whileve dosya okuma pattern'larında DRY prensibine yardımcı olur.
AI Asistan
Sorularını yanıtlamaya hazır