Kategori: Kod Kartları

  • Kod Kartı: Counter ile Kelime Saymak

    Kod Kartı: Counter ile Kelime Saymak

    Bir önceki kartta kelime sayacını get() ile kurmuştuk: boş sözlük, for döngüsü, sayac.get(k, 0) + 1. Python’un hazır gelen collections modülünde aynı işi tek satırda yapan bir araç var: Counter.

    Kod

    from collections import Counter
    kelimeler = ["python", "veri", "python", "bilim"]
    sayac = Counter(kelimeler)
    print(sayac) # Counter({'python': 2, 'veri': 1, 'bilim': 1})
    print(sayac.most_common(2)) # [('python', 2), ('veri', 1)]
    print(sayac["python"]) # 2
    print(sayac["java"]) # 0

    Counter bir listeyi alıyor ve her elemanın kaç kez geçtiğini tutan bir sözlük döndürüyor. most_common(n) en sık geçen n elemanı büyükten küçüğe veriyor. Eşit sayıları olanlar listede ilk görüldükleri sırayla geliyor; “veri”nin “bilim”den önce gelmesinin sebebi bu.

    Son satıra dikkat: Normal bir sözlükte olmayan anahtar KeyError verirdi. Counter ise 0 döndürüyor, çünkü “hiç görülmedi” ile “0 kez görüldü” aynı şey. Bu get(k, 0) ile yaptığımızın hazır hali.

    Metinde de çalışır

    Counter‘a bir metin verirsen harfleri sayar:

    print(Counter("bilgisayar").most_common(2)) # [('i', 2), ('a', 2)]

    Birkaç kullanışlı özellik

    sayac.update(["veri", "veri"]) # yeni elemanları sayıma ekle
    print(sayac) # Counter({'veri': 3, 'python': 2, 'bilim': 1})
    print(sum(sayac.values())) # 6 toplam kelime
    print(len(sayac)) # 3 farklı kelime
    a = Counter(elma=3, muz=1)
    b = Counter(elma=1, kiraz=2)
    print(a + b) # Counter({'elma': 4, 'kiraz': 2, 'muz': 1})
    print(a - b) # Counter({'elma': 2, 'muz': 1})

    İki sayacı toplayabilir ya da birinden diğerini çıkarabilirsin. Çıkarmada sıfır ya da eksi kalanlar listeden düşüyor; kirazın sonuçta olmamasının sebebi bu.

    Dikkat: saymadan önce temizle

    Counter ne verirsen onu sayar. Metni temizlemeden verirsen sonuç yanıltır:

    metin = "Python öğrenmek eğlenceli. python ile veri analizi de eğlenceli!"
    print(Counter(metin.split()).most_common(2))
    # [('Python', 1), ('öğrenmek', 1)] "Python" ile "python" farklı sayıldı
    temiz = [k.strip(".,!?").lower() for k in metin.split()]
    print(Counter(temiz).most_common(2))
    # [('python', 2), ('eğlenceli', 2)]

    Büyük-küçük harf ve noktalama yüzünden aynı kelime farklı sayılıyor. Türkçe metinlerde lower() yerine Python Dersi 11’deki tr_lower fonksiyonunu kullanmayı da unutma.

    Sözlükleri Python Dersi 8’de, get() kartını Kod Kartı #06’da, metin temizliğini Python Dersi 11’de anlattım.

  • Kod Kartı: Sözlükte Olmayan Anahtar: get() Kullan

    Kod Kartı: Sözlükte Olmayan Anahtar: get() Kullan

    Sözlükte olmayan bir anahtarı köşeli parantezle istersen Python programı durdurur: KeyError. Kullanıcıdan gelen bir isim, bir dosyadan okunan bir sütun ya da bir API’den dönen bir alan; hepsi “bu anahtar orada olmayabilir” durumları. get() bu durumda programı durdurmak yerine sana bir varsayılan değer verir.

    Kod

    notlar = {"Ayşe": 85, "Mert": 45}
    print(notlar["Zeynep"]) # KeyError: 'Zeynep'
    print(notlar.get("Zeynep")) # None
    print(notlar.get("Zeynep", 0)) # 0
    print(notlar) # {'Ayşe': 85, 'Mert': 45}

    get iki şey alıyor: aranan anahtar ve anahtar yoksa dönecek değer. İkincisini yazmazsan None döner. Son satıra dikkat: get sözlüğe hiçbir şey eklemiyor, sadece okuyor.

    En sık kullanımı: sayaç

    Python Dersi 8’deki kelime sayacını hatırla:

    oylar = ["elma", "muz", "elma"]
    sayac = {}
    for oy in oylar:
    sayac[oy] = sayac.get(oy, 0) + 1
    print(sayac) # {'elma': 2, 'muz': 1}

    Bir meyve ilk kez görüldüğünde sözlükte yok, get 0 veriyor, üstüne 1 ekleniyor. Sonraki seferlerde mevcut sayı geliyor. get olmasaydı her seferinde if oy in sayac: diye kontrol etmek gerekirdi.

    Dikkat: anahtar var ama değeri None

    Varsayılan değer sadece anahtar hiç yoksa devreye girer. Anahtar varsa, değeri None bile olsa o döner:

    ayarlar = {"tema": None}
    print(ayarlar.get("tema", "açık")) # None, "açık" değil!
    print(ayarlar.get("dil", "tr")) # tr

    Veriyi bir yerden okurken boş alanlar sık sık None olarak gelir. “Yoksa ya da boşsa varsayılanı kullan” demek istiyorsan bunu ayrıca kontrol etmen gerekiyor.

    Ne zaman get(), ne zaman köşeli parantez?

    • Anahtarın mutlaka olması gerekiyorsa sözlük[anahtar] kullan. Yoksa ortada bir hata vardır ve KeyError bunu sana hemen söyler.
    • Anahtarın olmaması normalse get kullan ve mantıklı bir varsayılan ver.

    get her hatayı susturmak için değil. Yanlış yazılmış bir anahtarı ("Ayse" yerine "Ayşe") sessizce 0’a çevirirse hatayı bulmak çok daha zorlaşır.

    Sözlükleri Python Dersi 8’de, fonksiyonları ve varsayılan değerleri Python Dersi 9’da anlattım.

  • Kod Kartı: Liste Üreteciyle Tek Satırda Filtre

    Kod Kartı: Liste Üreteciyle Tek Satırda Filtre

    Bir listeden şarta uyan elemanları seçip yeni bir liste yapmak için dört satır yazıyorduk: boş liste, for, if, append. Liste üreteci (list comprehension) aynı işi tek satırda yapıyor.

    İtiraf edeyim, Python öğrenirken bana en zor gelen konulardan biri buydu. İlk gördüğümde satırın nereden başlayıp nerede bittiğini çözemiyordum. Aşağıdaki okuma yöntemini öğrenince her şey yerine oturdu.

    Kod

    notlar = [70, 85, 40, 90, 45]
    # Dört satırlık hali
    gecenler = []
    for n in notlar:
    if n >= 50:
    gecenler.append(n)
    # Tek satırlık hali
    gecenler = [n for n in notlar if n >= 50]
    print(gecenler) # [70, 85, 90]

    Bu satır nasıl okunur?

    [n for n in notlar if n >= 50] satırını soldan sağa şöyle oku: “Listeye n‘yi koy, notlar içindeki her n için, eğer n 50 veya üstüyse.” Yani dört satırlık kodun parçaları aynı, sadece yerleri değişmiş: listeye eklenecek şey en başa, for ortaya, if sona geliyor. Köşeli parantezler de “sonuç bir liste” demek.

    Filtrelemenin yanında dönüştürme

    Baştaki kısımda sadece n yazmak zorunda değilsin; her elemanı değiştirebilirsin:

    print([n + 5 for n in notlar])
    # [75, 90, 45, 95, 50] herkese 5 puan
    print([n + 5 for n in notlar if n < 50])
    # [45, 50] sadece kalanlara 5 puan, sadece onları listele
    isimler = ["ayşe", "mert", "zeynep"]
    print([i.capitalize() for i in isimler])
    # ['Ayşe', 'Mert', 'Zeynep']

    _ ne demek?

    Matrix yağmuru yazısındaki şu satırı hatırla:

    damlalar = [random.randint(-yukseklik, 0) for _ in range(genislik)]

    Burada döngü değişkenini hiç kullanmıyoruz; sadece genislik kadar rastgele sayı üretmek istiyoruz. Python’da kullanılmayan değişkene genelde _ adı verilir. Bu, okuyana “bu değere ihtiyacım yok, sadece tekrar sayısı önemli” der.

    Dikkat

    Liste üreteci kısa ve okunaklı olduğunda güzel. Ama içine çok şey sıkıştırırsan okunmaz hale gelir:

    # Okuması zor
    [n * 2 if n > 60 else n for n in notlar if n % 5 == 0 and n != 45]

    Bir satırı okumak için birkaç kez durman gerekiyorsa dört satırlık for döngüsüne geri dön. Kodu kısa yazmak değil, anlaşılır yazmak amaç.

    Listeleri Python Dersi 7’de, for ve if‘i Python Dersi 5 ve 6’da anlattım.

  • Kod Kartı: zip ile İki Listeyi Birlikte Gezmek

    Kod Kartı: zip ile İki Listeyi Birlikte Gezmek

    Elinde birbirine ait iki liste var: bir yanda öğrenci isimleri, öbür yanda notları. İkisini aynı anda gezmek için indeks hesabına girmene gerek yok. zip iki listeyi fermuar gibi birleştirir ve elemanları çift çift verir.

    Kod

    isimler = ["Ayşe", "Mert", "Zeynep"]
    notlar = [85, 70, 92]
    for isim, puan in zip(isimler, notlar):
    print(f"{isim}: {puan}")
    # Ayşe: 85
    # Mert: 70
    # Zeynep: 92

    Bu satır nasıl çalışıyor?

    zip(isimler, notlar) iki listenin aynı sıradaki elemanlarını eşleştirir: önce ("Ayşe", 85), sonra ("Mert", 70), sonra ("Zeynep", 92). Adı da buradan geliyor: fermuarın (zip) iki tarafı diş diş birbirine geçer.

    for isim, puan in ... yazınca her çift, enumerate kartındaki gibi iki değişkene dağıtılır. Çiftlerin hepsini birden görmek istersen listeye çevirebilirsin:

    print(list(zip(isimler, notlar)))
    # [('Ayşe', 85), ('Mert', 70), ('Zeynep', 92)]

    zip olmadan aynı iş şöyle yapılır:

    for i in range(len(isimler)):
    print(f"{isimler[i]}: {notlar[i]}")

    Çalışır, ama isimler[i], notlar[i] diye her seferinde indeksle uğraşmak hem okumayı zorlaştırır hem de hata yapmaya açık kapı bırakır. zip‘li hali ne yaptığını kendisi anlatıyor.

    İkiden fazla liste

    zip istediğin kadar listeyi birleştirebilir:

    sehirler = ["Adana", "İzmir", "Ankara"]
    for isim, puan, sehir in zip(isimler, notlar, sehirler):
    print(f"{isim} ({sehir}): {puan}")
    # Ayşe (Adana): 85
    # Mert (İzmir): 70
    # Zeynep (Ankara): 92

    Dikkat

    Listelerin uzunluğu farklıysa zip en kısa liste bitince durur ve hata vermez:

    kisa = ["Ayşe", "Mert"]
    print(list(zip(kisa, notlar)))
    # [('Ayşe', 85), ('Mert', 70)] 92 sessizce kayboldu

    Bir listeye eleman eklemeyi unuttuysan bunu fark etmeyebilirsin. Python 3.10 ve sonrasında zip(kisa, notlar, strict=True) yazarsan uzunluklar farklı olduğunda hata alırsın ve sorunu hemen görürsün.

    Döngüleri Python Dersi 6’da, listeleri Python Dersi 7’de anlattım.

  • Kod Kartı: enumerate: Sayaç Tutmayı Bırak

    Kod Kartı: enumerate: Sayaç Tutmayı Bırak

    Bir listeyi döngüyle gezerken elemanların sıra numarasına da ihtiyaç duyuyorsan, ayrı bir sayaç değişkeni tutmana gerek yok. enumerate her elemanı numarasıyla birlikte verir.

    Kod

    urunler = ["Kalem", "Defter", "Silgi"]
    for sira, urun in enumerate(urunler, start=1):
    print(f"{sira}. {urun}")
    # 1. Kalem
    # 2. Defter
    # 3. Silgi

    Bu satır nasıl çalışıyor?

    enumerate(urunler) listedeki her elemanı bir sıra numarasıyla eşleştirir: (0, "Kalem"), (1, "Defter"), (2, "Silgi"). for sira, urun in ... yazınca bu çiftler, takas kod kartında gördüğümüz paket açma mantığıyla iki değişkene dağıtılır.

    Python saymaya 0’dan başlar. start=1 yazarak numaraların 1’den başlamasını sağladık; ekrana yazdırılacak listeler için genelde bunu istersin.

    enumerate olmadan aynı iş şöyle yapılır:

    sira = 0
    for urun in urunler:
    sira += 1
    print(f"{sira}. {urun}")

    Çalışır, ama sayacı artırmayı unutmak ya da yanlış yerde artırmak çok kolay. enumerate bu sorumluluğu senden alıyor.

    Bir örnek daha: hangi sıradaki eleman?

    Numara, bir elemanın listede nerede olduğunu söylemek istediğinde de işe yarar:

    notlar = [70, 85, 40, 90]
    for sira, puan in enumerate(notlar, start=1):
    if puan < 50:
    print(f"{sira}. öğrenci kaldı ({puan})")
    # 3. öğrenci kaldı (40)

    Buradaki if‘i Python Dersi 5’te gördük; for döngüsünü ise Python Dersi 6’da ayrıntılı işleyeceğiz.

    Dikkat

    for satırında iki değişken yazmayı unutursan hata almazsın ama çıktı beklemediğin gibi olur:

    for eleman in enumerate(urunler):
    print(eleman)
    # (0, 'Kalem')
    # (1, 'Defter')
    # (2, 'Silgi')

    eleman her seferinde numara ve değerden oluşan bir demet (tuple). Numarayı ve değeri ayrı ayrı kullanmak istiyorsan for sira, urun in ... şeklinde iki isim ver.

  • Kod Kartı: f-string ile Şık Çıktılar

    Kod Kartı: f-string ile Şık Çıktılar

    Ekrana metin ile değişkeni birlikte yazdırmak istediğinde artı işaretleri ve str() çağrılarıyla uğraşmana gerek yok. Metnin başına bir f koy, değişkeni süslü paranteze yaz.

    Bu konuyu videoda da anlattım. İzleyerek öğrenmeyi seviyorsan buradan başlayabilirsin 👇

    Kodları kendin çalıştırmak istersen Colab defteri burada: [Colab linki]

    Kod

    isim = "Ayşe"
    not_ortalamasi = 87.456
    # Eski yol: + ile birleştirmek, sayıyı str() ile metne çevirmek
    print("Merhaba " + isim + ", ortalaman " + str(not_ortalamasi))
    # f-string ile
    print(f"Merhaba {isim}, ortalaman {not_ortalamasi}")
    # Merhaba Ayşe, ortalaman 87.456

    Bu satır nasıl çalışıyor?

    Tırnaktan önceki f, Python’a “bu metnin içindeki süslü parantezlere bak” der. Python her {...} içindeki ifadeyi hesaplar, sonucu metne çevirir ve yerine yazar. Sayıyı kendin metne çevirmen gerekmez.

    Süslü parantezin içine sadece değişken değil, küçük bir işlem de yazabilirsin:

    print(f"Gelecek yıl {2026 + 1} olacak") # Gelecek yıl 2027 olacak
    print(f"İsmin {len(isim)} harfli") # İsmin 4 harfli

    Şık çıktılar: biçimlendirme

    Asıl gücü burada. Süslü parantezin içine iki nokta koyup bir biçim yazabilirsin.

    Virgülden sonra kaç basamak:

    print(f"Ortalaman: {not_ortalamasi:.1f}") # Ortalaman: 87.5

    .1f “virgülden sonra 1 basamak göster” demek; Python yuvarlamayı kendisi yapar.

    Yüzde:

    oran = 0.4567
    print(f"Başarı oranı: {oran:.0%}") # Başarı oranı: 46%

    Hizalı bir tablo:

    urunler = [("Kalem", 12.5), ("Defter", 45), ("Silgi", 7.25)]
    for ad, fiyat in urunler:
    print(f"{ad:<8}{fiyat:>8.2f} TL")
    # Kalem 12.50 TL
    # Defter 45.00 TL
    # Silgi 7.25 TL

    <8 metni 8 karakterlik alana sola, >8.2f sayıyı 8 karakterlik alana sağa yaslıyor ve 2 basamak gösteriyor.

    Hata ayıklama kısayolu: Değişkenin adını da görmek istersen sonuna eşittir koy.

    x = 5
    print(f"{x = }") # x = 5

    Dikkat

    Baştaki f harfini unutursan Python hata vermez ama süslü parantezleri olduğu gibi yazar:

    print("Ortalaman: {not_ortalamasi}") # Ortalaman: {not_ortalamasi}

    Çıktıda süslü parantez görüyorsan ilk bakılacak yer baştaki f.

    f-string’i Python serisinin 4. dersinde, input ve print ile kullanıcıyla konuşan bir program yazarken sık sık kullanacağız.

  • Kod Kartı: Python’da İki Değişkeni Tek Satırda Takas Etmek

    Kod Kartı: Python’da İki Değişkeni Tek Satırda Takas Etmek

    İki değişkenin değerini yer değiştirmen gerektiğinde Python’da geçici bir değişkene ihtiyacın yok. Tek satır yeter.

    Kod

    a = 5
    b = 9
    a, b = b, a # sağdaki değerler önce okunur, sonra sola yazılır
    print(a, b) # 9 5

    Bu satır nasıl çalışıyor?

    Python eşittirin önce sağ tarafını değerlendirir. b, a yazıldığı anda iki değer, yani 9 ve 5, bir demet (tuple) içinde paketlenir. Sonra bu paket açılır ve değerler sırayla soldaki isimlere dağıtılır: ilk değer a‘ya, ikincisi b‘ye. Değerler önceden okunduğu için hiçbir değer kaybolmaz.

    Başka birçok dilde aynı iş için üç satır ve geçici bir değişken yazarsın:

    gecici = a
    a = b
    b = gecici

    Python’da bu da çalışır, ama tek satırlık versiyon hem daha kısa hem daha okunaklı.

    Bir örnek daha: listede iki elemanı takas etmek

    Aynı yöntem bir listenin elemanları için de işler. Sıralama algoritmalarında sık karşına çıkacak:

    sayilar = [3, 1, 2]
    sayilar[0], sayilar[2] = sayilar[2], sayilar[0] # ilk ve son elemanı takas et
    print(sayilar) # [2, 1, 3]

    Dikkat

    Sol ve sağ taraftaki eleman sayısı aynı olmalı. a, b = 1, 2, 3 yazarsan Python ValueError: too many values to unpack (expected 2) hatası verir: üç değeri iki kutuya sığdıramaz.

    Bu yöntemin arkasındaki demet (tuple) kavramını Python serisinin 8. dersinde, Sözlükler ve Demetler’de ayrıntılı işleyeceğiz.