Python Veri Yapıları: Listeler, Sözlükler ve Setlerle Pratik Örnekler
Python Veri Yapıları

Python Veri Yapıları: Listeler, Sözlükler ve Setlerle Pratik Örnekler

Python Veri Yapıları

8 dk okuma süresi
Bu rehber, Python’daki list, dict ve set veri yapılarını kısa tanımlar ve çalıştırılabilir örneklerle açıklar. List/dict/set seçimini kolaylaştıran bir karar özeti, comprehension örnekleri ve mutable–immutable farkının pratik etkileri de yer alır.
Python Veri Yapıları: Listeler, Sözlükler ve Setlerle Pratik Örnekler

Python’da veri yapıları neden önemli?

Python’da aynı problemi birden fazla şekilde çözebilirsiniz; çoğu zaman farkı yaratan şey hangi veri yapısını seçtiğiniz olur. Listeler (list), sözlükler (dict) ve setler (set) günlük geliştirme işlerinde en sık karşınıza çıkan üç temel yerleşik (built-in) koleksiyondur. Bu yazıda her birini kopyalayıp çalıştırabileceğiniz kısa örneklerle ele alacağız.

Davranış ve metotları doğrulamak için resmi dokümantasyon iyi bir başlangıçtır: Built-in Types (stdtypes) ve Python Tutorial: Data Structures.


Hızlı karşılaştırma: list vs dict vs set

Tip Ne için ideal? Sıralı mı? Tekrara izin verir mi? Değiştirilebilir mi (mutable)?
list Sıralı koleksiyon, indeksle erişim Evet Evet Evet
dict Anahtar → değer eşlemesi Python 3.7+: eklenme sırası dil seviyesinde garantidir (3.6: CPython ayrıntısı) Anahtarlar benzersizdir Evet
set Benzersiz elemanlar, küme işlemleri Hayır (sırasız) Hayır Evet

Özelliklerin ayrıntıları için resmi referans: Python 3 stdtypes.


1) Listeler (list): sıralı ve değiştirilebilir koleksiyon

Liste, elemanların sırasını koruyan ve içerik üzerinde yerinde (in-place) değişiklik yapabildiğiniz bir koleksiyondur. İndeksleme ve dilimleme (slicing) günlük kullanımın temel parçalarıdır. Detaylar için: stdtypes: list ve Tutorial: Data Structures.

Liste oluşturma, indeksleme, dilimleme

Ne gösterir: Liste oluşturma, negatif indeks ve slicing.

# Oluşturma
nums = [10, 20, 30]
words = list(("hello", "python"))

# İndeksleme
first = nums[0] # 10
last = nums[-1] # 30

# Dilimleme (slicing)
subset = nums[0:2] # [10, 20]
copy_like = nums[:] # sığ kopya (shallow copy)

Çıktı/Notlar: nums[:] yeni bir liste üretir; ancak iç içe (nested) yapılar varsa bu kopya “sığ” kalır.

Sık kullanılan liste metotları

Gündelik işlerde en çok kullanılanlar: append, extend, insert, pop, remove, sort, reverse, copy. Resmi metot listesi: Data Structures.

Ne gösterir: Ekleme/çıkarma ve yerinde sıralama.

items = ["a", "b"]
items.append("c")
items.extend(["d", "e"])
items.insert(1, "X")

last = items.pop() # "e"
items.remove("X") # ilk eşleşeni siler

items.sort() # yerinde sıralar
items.reverse() # yerinde ters çevirir

Çıktı/Notlar: sort() listeyi yerinde değiştirir ve None döndürür. Sıralanmış bir kopya için sorted(items) kullanın.

List comprehension: kısa ve okunabilir dönüşümler

List comprehension, bir listeyi dönüştürmenin/filtrelemenin kompakt bir yoludur. Örnekler için: Tutorial: Data Structures. Okunabilirlik ve pratik notlar için: Real Python — List Comprehensions.

Ne gösterir: Dönüştürme, filtreleme, birlikte kullanım.

# 1) Dönüştürme: her elemanın karesi
squares = [x * x for x in range(6)]

# 2) Filtreleme: sadece çift sayılar
evens = [x for x in range(10) if x % 2 == 0]

# 3) Hem filtre hem dönüşüm
labels = [f"user_{i}" for i in range(1, 6) if i != 3]

Beklenen sonuç: squares 0–25 arası kareleri, evens çiftleri, labels ise “user_3” hariç etiketleri üretir.

Not: Performans hakkında genelleme yaparken dikkatli olun: bazı durumlarda list comprehension pratikte hızlı olabilir; ancak sonuçlar Python sürümüne, veri boyutuna ve iç işlemlere göre değişir. En sağlıklısı, kendi ortamınızda küçük bir timeit deneyi yapmaktır.

Listelerde yaygın tuzak: paylaşılan (aliased) referanslar

Listeler mutable olduğu için aynı listeyi birden fazla yere “paylaştırmak” beklenmedik yan etkiler yaratabilir. Bu, özellikle atama/kopyalama yaparken önem kazanır. Arka plan için: stdtypes ve pratik notlar için Real Python.

Ne gösterir: Aynı listeyi iki değişkenin işaret etmesi (aliasing) ve copy() ile yeni liste almak.

a = [1, 2, 3]
b = a # b ve a aynı listeyi işaret eder
b.append(4)
# a artık [1, 2, 3, 4]

# Yeni liste nesnesi (sığ kopya):
c = a.copy()
c.append(5)
# a değişmez, c değişir

Çıktı/Notlar: b = a bir kopya üretmez; aynı nesne üzerinde çalışırsınız. Kopya gerekiyorsa copy() ya da dilimleme gibi yaklaşımları bilinçli kullanın.


2) Sözlükler (dict): anahtar → değer haritaları

dict, bir anahtarın (key) bir değere (value) karşılık geldiği haritalama tipidir. Birçok senaryoda (ayarlar, sayımlar, özellikler, önbellekler) doğal seçimdir. Ana referans: stdtypes: dict.

Sıra notu (sürüm vurgusu): Dict’in eklenme sırasını koruması Python 3.7+ için dil seviyesinde garantidir; Python 3.6 için bu davranış CPython’ın bir uygulama ayrıntısı olarak görülür. Detaylar için: stdtypes.

Dict oluşturma ve güvenli okuma

Ne gösterir: [] ile okuma ve get() ile varsayılan değer.

user = {"id": 7, "name": "Ada"}

# Doğrudan erişim (anahtar yoksa KeyError oluşur):
name = user["name"]

# get() ile varsayılan değer:
age = user.get("age", 0) # age yoksa 0 döner

Çıktı/Notlar: Dışarıdan gelen/veri kalitesi belirsiz sözlüklerde get() ile okumak, kontrol akışını sadeleştirebilir.

İterasyon: keys(), values(), items()

Ne gösterir: Anahtar/değer/çiftler üzerinde dolaşma.

settings = {"theme": "dark", "lang": "tr"}

for key in settings.keys():
    print(key)

for value in settings.values():
    print(value)

for key, value in settings.items():
    print(key, value)

Çıktı/Notlar: Pratikte çoğu zaman for key, value in d.items() okunabilir bir varsayılandır.

setdefault(): “yoksa oluştur” desenleri

setdefault() özellikle gruplama ve liste biriktirme işlerinde kullanışlıdır. Metot davranışı için: stdtypes: dict.

Ne gösterir: Uzunluğa göre gruplama (liste biriktirme).

words = ["hi", "python", "data", "set"]
groups = {}
for w in words:
    groups.setdefault(len(w), []).append(w)

Beklenen sonuç: groups içinde anahtarlar uzunluk, değerler o uzunluktaki kelimeler listesi olur (ör. 4 → ["data", "set"]).

Alternatif olarak collections.defaultdict da tercih edilebilir; ancak bu yazı yerleşik tiplerle odakta kalır.

Dict comprehension: hızlı dönüştürmeler

Ne gösterir: Sayıların karelerini anahtar-değer olarak üretme.

d = {x: x * x for x in range(5)}

Beklenen sonuç: 0→0, 1→1, 2→4 … şeklinde bir eşleme oluşur.

Önemli kural: dict anahtarları hashable olmalı

dict anahtarı olarak kullanılan nesneler “hashable” olmalıdır. Bu yüzden list veya dict gibi mutable tipler anahtar olamaz; tuple gibi immutable tipler çoğu durumda uygundur. Kuralın arka planı için: stdtypes.

Ne gösterir: Uygun/uygunsuz anahtar örnekleri ve bir kenar durum.

# Uygun değil: list hashable değildir (anahtar olamaz)
# d1 = {[1, 2]: "x"}

# Uygun: tuple çoğu durumda anahtar olabilir
d2 = {(1, 2): "x"}

# Kenar durum: tuple immutable olsa da içinde hashable olmayan öğe varsa olmaz
# d3 = {([1, 2], 3): "x"}

Çıktı/Notlar: Böyle bir ihtiyaçta veriyi tamamen immutable bir temsile dönüştürmek (ör. sadece sayı/string içeren tuple) veya farklı bir anahtar stratejisi seçmek gerekir.


3) Setler (set): benzersiz elemanlar ve küme işlemleri

set, benzersiz öğeleri tutan ve matematiksel küme işlemlerini destekleyen bir koleksiyondur. Tanım ve operasyonlar için: stdtypes: set ve eğitim dokümanı: Python Tutorial — Data Structures.

Set oluşturma ve üyelik testi

Ne gösterir: Tekrar eklemenin etkisi ve üyelik kontrolü.

nums = {1, 2, 3}
nums.add(3) # zaten varsa küme aynı kalır
nums.add(4) # {1, 2, 3, 4}

exists = 2 in nums # True

Çıktı/Notlar: Üyelik testinde set/dict çoğu durumda pratiktir; büyük veri kararlarında ölçüm yapmak iyi bir alışkanlıktır.

Küme operasyonları: union, intersection, difference

Ne gösterir: Birleşim, kesişim, fark ve simetrik fark.

a = {1, 2, 3, 4}
b = {3, 4, 5}

union = a | b
intersect = a & b
diff = a - b
sym_diff = a ^ b

Beklenen sonuç: union {1,2,3,4,5}, intersect {3,4}, diff {1,2}, sym_diff {1,2,5}. (Set çıktılarında sıra garantisi olmadığını unutmayın.)

Aynı işlemleri metotlarla da yapabilirsiniz: a.union(b), a.intersection(b), a.difference(b), a.symmetric_difference(b). Ayrıntı için: stdtypes: set.

Set comprehension ve frozenset

Ne gösterir: Tekilleştirme ve immutable set (frozenset).

# Set comprehension: benzersiz kareler
sq = {x * x for x in [1, 2, 2, 3]}

# Değiştirilemez set: frozenset
fs = frozenset([1, 2, 3])

Çıktı/Notlar: frozenset immutable olduğu için bazı senaryolarda dict anahtarı veya başka setlerin elemanı olarak kullanılabilir. Tanım için: stdtypes.


Mutable vs immutable: pratikte neyi değiştirir?

Python’da bazı tipler değiştirilebilir (mutable), bazıları değiştirilemez (immutable) davranır. Bu fark iki yerde özellikle hissedilir:

  • Fonksiyonlara parametre geçerken: Mutable nesne üzerinde yerinde değişiklik yapılırsa, çağıran taraf da bu değişimi görür.
  • Hashing gereken yerlerde: dict anahtarı veya set elemanı olmak için hashable bir temsil gerekir (çoğu durumda immutable tipler).

Resmi davranışlar için: stdtypes. Pratik yorumlar için: Real Python.

Fonksiyonlarda yan etkiyi kontrol etme

Ne gösterir: Listeyi yerinde değiştiren fonksiyonun çağırana etkisi.

def add_tag(tags, tag):
    tags.append(tag) # yerinde değişiklik

my_tags = ["python"]
add_tag(my_tags, "data")
# my_tags artık ["python", "data"]

Eğer yan etki istemiyorsanız, fonksiyon içinde kopya ile çalışabilirsiniz:

Ne gösterir: Kopya alarak yeni liste döndürme.

def add_tag_safely(tags, tag):
    new_tags = tags.copy()
    new_tags.append(tag)
    return new_tags

my_tags = ["python"]
result = add_tag_safely(my_tags, "data")
# my_tags değişmez, result yeni listedir

Çıktı/Notlar: İç içe yapılar varsa sığ kopya her durumu çözmeyebilir; böyle senaryolarda veri modelini sade tutmak veya farklı bir yaklaşım seçmek gerekebilir.


Ne zaman hangisini seçmeliyim? (Mini karar rehberi)

  • Sıra önemliyse ve aynı eleman birden fazla kez bulunabiliyorsa: list
  • Bir şeyi anahtarla bulmak istiyorsanız (id → kayıt, isim → değer): dict
  • Benzersiz elemanlar ve küme işlemleri (kesişim/fark) istiyorsanız: set

Kısa kontrol listesi

  • Listelerde: kopya mı istiyorsunuz, yoksa aynı liste üzerinde mi çalışıyorsunuz? (Aliasing riskini düşünün.)
  • Dict’te: Anahtarınız gerçekten hashable mı?
  • Set’te: Çıktı sırası üzerine mantık kurmayın; set sırasızdır.
  • Comprehension kullanırken: Okunabilirlik bozuluyorsa basit bir for döngüsü daha iyi olabilir.

Basit bir timeit iskeleti (isteğe bağlı)

Aşağıdaki iskelet, kendi ortamınızda küçük karşılaştırmalar yapmak için bir başlangıçtır. Sonuçlar; Python sürümü, işletim sistemi ve veri boyutuna göre değişebilir.

Ne gösterir: Belirli bir ifadeyi çok kez çalıştırıp süre ölçümü.

import timeit

setup = "data = list(range(10000))"
stmt = "[x * 2 for x in data]"
print(timeit.timeit(stmt=stmt, setup=setup, number=200))

Not: Gerçek hayattaki iş yükünüzü temsil eden veri ve işlemlerle ölçüm yapmaya çalışın.


Sonuç

List, dict ve set; Python’da hem öğrenmesi kolay hem de doğru kullanıldığında üretkenliği artıran temel veri yapılarıdır. Listeler sıralı dönüşümler için, dict’ler anahtar-temelli erişim için, set’ler benzersizlik ve küme işlemleri için güçlüdür. Mutable vs immutable farkını akılda tutarak kopyalama/yan etki konularını yönetebilir, comprehension’ları da okunabilirlik çizgisini aşmadan kullanabilirsiniz.

Kaynaklar ve ileri okuma

Sources (resmi dokümanlar)

Yorumlar

Henüz yorum yapılmamış. İlk yorumu sen yaz.