Koleksiyonlar, değiştirilebilirlik ve referans sezgisi

Nesne tabanlı programlamaya geçmeden önce Python’da birden fazla değeri nasıl tuttuğumuzu ve değişken adlarının bu değerlerle nasıl ilişkilendiğini anlamamız gerekir. Bu hafta liste, demet, sözlük ve kümeleri hızlıca kullanacağız; ancak asıl öncelik değiştirilebilirlik (mutability), aynı nesneyi paylaşma (aliasing) ve kopyalama olacaktır. Dört koleksiyonun bütün ayrıntılarını tek haftada ezberlemek beklenmez.

Bu bölümün kapsamı

NoteSınavda sorulur
  • list, tuple, dict ve set arasından uygun koleksiyonu seçme
  • demetin değişmezliğinin içindeki nesneyi kapsamaması
  • b = a sonrası iki adın aynı nesneyi göstermesi
  • is ile == sorularının ayrımı
  • copy() ile bağımsız kopya ve sığ kopyanın sınırı
  • sözlükte .keys(), .values() ve .items() görünümleri
  • sorted() ile .sort() farkı
  • copy.deepcopy() ayrıntıları
  • collections modülündeki yardımcı yapılar
  • küme işlemleri (birleşim, kesişim) ayrıntısı

Bu başlıklar konunun devamıdır; ileride karşınıza çıkar ama bu derste ezberlemeniz beklenmiyor.

İki değişken aynı listeyi ne zaman gösterir?

Bu bölümün asıl kazanımı koleksiyon listesi ezberlemek değildir. İki adın aynı değiştirilebilir nesneyi gösterebildiğini ve bir yerdeki değişikliğin diğer yerden görüldüğünü anlamaktır. Nesne tabanlı programlamanın merkezine giden yol buradan geçer.

NoteBu haftanın çekirdek önceliği

Ders süresi sınırlıysa set ayrıntıları ve iç içe sığ kopya örnekleri ikinci plandadır. OOP’ye hazırlık açısından en kritik kazanım, iki adın aynı mutable nesneyi gösterebildiğini ve bir yerdeki değişikliğin diğer yerden görülebildiğini gerçekten anlamaktır.

Dört temel koleksiyon

Yapı Temel fikir Değiştirilebilir? Tipik kullanım
list sıralı değerler evet notlar, ürünler, adımlar
tuple sabit sıralı grup hayır koordinat, değişmez kayıt parçası
dict anahtar → değer evet öğrenci no → öğrenci bilgisi
set benzersiz değerler evet üyelik, tekrarları kaldırma

Kümede "python" iki kez yazılsa bile yalnızca bir kez tutulur.

Liste değişir, demet değişmez

Aynı işlemi tuple üzerinde yapmaya çalışmak TypeError üretir:

point = (10, 20)
point[0] = 99  # hata

Buradaki değiştirilemezlik, tuple’ın eleman bağlarının sonradan yeniden atanamaması anlamına gelir. Ancak bir tuple’ın içinde değiştirilebilir bir nesne bulunabilir:

Tuple’ın kendisine yeni bir eleman atamadık; tuple içindeki liste nesnesinin durumunu değiştirdik. Bu ayrım, “immutable” sözcüğünü bütün iç yapının derinlemesine değişmez olduğu şeklinde yorumlamamayı sağlar.

Bir demetin kendisi değişmezken içinde tuttuğu değiştirilebilir nesnenin durumunun değişebildiğini gösteren diyagram.

Demet içinde değiştirilebilir nesne

Kritik deney: iki ad, bir liste

Aşağıdaki kodu çalıştırmadan önce çıktıyı tahmin edin.

second = first yeni bir liste oluşturmaz. İki değişken adı aynı liste nesnesini gösterir.

İki adın aynı listeyi göstermesi ile bağımsız bir kopya oluşturulması arasındaki fark.

Aliasing ve kopya

Bunu id() ve is ile gözlemleyebiliriz:

is, iki ifadenin aynı nesneye gönderme yapıp yapmadığını; == ise değerlerin eşit kabul edilip edilmediğini sorgular.

ImportantBu fikir OOP’nin merkezine gidecek

Gelecek haftalarda account, customer, order gibi değişkenlerin birer nesneyi göstereceğini göreceğiz. Bir nesneyi metotla değiştirdiğimizde, aynı nesneye referansı olan diğer yerler de yeni durumu görür. Bugünkü liste deneyi bunun küçük bir ön gösterimidir.

Eşit ama aynı olmayan iki liste

İçerikleri eşit olabilir ama iki ayrı liste nesnesidir.

Kopya oluşturmak

Yeni ve ayrı bir liste istediğimizde en açık seçeneklerden biri .copy() ile sığ kopyadır:

Aynı dış listeyi list(original) veya original[:] ile de kopyalayabilirsiniz; bu derste okunabilirlik için .copy() kullanacağız.

Ancak sığ kopya (shallow copy) ifadesindeki “sığ” sözcüğü önemlidir. İç içe listelerde içteki nesneler hâlâ paylaşılabilir:

Bu hafta deepcopy ayrıntısına girmiyoruz. Ama bir kopyanın neyi gerçekten ayırdığını sorgulama alışkanlığı önemlidir.

Sözlükle kayıt tutmak ve dolaşmak

Sözlük üzerinde doğrudan dolaşırsanız anahtarları alırsınız. Anahtar ve değeri birlikte kullanmak için .items() çoğu zaman en doğal araçtır:

  • .keys() anahtar görünümü,
  • .values() değer görünümü,
  • .items() (anahtar, değer) çiftleri verir.

Sözlük anahtarı neden her şey olamaz?

Sözlük ve küme, hash tabanlı yapılardır. Bir sözlük anahtarının hashlenebilir olması gerekir; pratik başlangıç kuralı olarak değiştirilebilir list, dict ve set nesnelerini anahtar yapmayın:

lookup = {}
lookup[[1, 2]] = "değer"  # TypeError: unhashable type: 'list'

str, int ve uygun immutable tuple’lar sık kullanılan anahtarlardır. 12. haftada kendi sınıflarımızda __eq__ ve hash sözleşmesinin ilişkisini yeniden göreceğiz.

sorted() ve .sort()

İki isim benzer, etkileri farklıdır:

  • sorted(iterable) yeni bir liste döndürür; asıl koleksiyonu değiştirmez.
  • list.sort() mevcut listeyi yerinde değiştirir ve None döndürür.

Nesne koleksiyonlarını sıralarken de aynı ayrım geçerli olacaktır.

Alıştırma — Doğru koleksiyonu seç

Aşağıdaki ihtiyaçlar için list, tuple, dict veya set seçeneklerinden en uygun olanı seçin ve bir cümleyle gerekçelendirin:

  1. Bir dersin haftalık konu sırası.
  2. Öğrenci numarasından öğrenci adına hızlı erişim.
  3. Sisteme giriş yapan benzersiz kullanıcı adları.
  4. Değişmemesi gereken (enlem, boylam) çifti.

Tek bir “mutlak doğru” yerine kullanım amacına bakın.

Alıştırma — Aliasing hatasını düzelt

Aşağıdaki kodda backup değişmeden kalması bekleniyor:

backup için ayrı liste oluşacak biçimde tek satırı .copy() kullanarak değiştirin.

Alıştırma — Frekans sözlüğü

counts.get(word, 0) ifadesi anahtar yoksa 0 döndürür.

counts[word] = counts.get(word, 0) + 1

Küçük üretim görevi — Basit envanter

Ürün kodlarını anahtar, stok miktarlarını değer olarak tutan bir sözlük oluşturun. Ardından:

  • Bir ürünün stokunu azaltın,
  • Olmayan ürün için güvenli kontrol yapın,
  • .items() ile dolaşıp stoku sıfır olan ürünleri listeleyin,
  • sorted() kullanarak ürün kodlarını sıralı raporlayın,
  • Tüm ürün kodlarının benzersiz olduğunu açıklayın.

Son olarak şu soruyu cevaplayın: “Stok sıfırın altına düşmesin” kuralını bu sözlük yaklaşımında nerede koruyoruz? Bu sorunun cevabı, ileride neden sınıf metotlarına ihtiyaç duyacağımızı gösterecek.

Çalışır kod teslimi: Envanter programını en az bir mevcut, bir olmayan ve bir stoku sıfır ürün senaryosuyla çalıştırın. Çıktıda bu üç durum görünür olmalıdır.

Sınav provası

Önce kendi cevabını seç; sonra cevap anahtarında her şıkkın neden doğru veya yanlış olduğunu oku. Çeldiriciler uydurma değil, bu konuda gerçekten yapılan hatalardır. Sınav maddeleri de bu mantıkla yazılır.

Madde 1. Bir metindeki benzersiz kelimeleri tutmak için en uygun koleksiyon hangisidir?

  • A. tuple; değiştirilemez olduğu için tekrar eklenemez
  • B. list; sıra korunduğu için tekrar sorunu oluşmaz
  • C. str; kelimeler zaten metin olduğu için
  • D. set; tekrarları kendiliğinden eler ve üyelik sorusuna doğrudan cevap verir
  • E. dict; anahtarlar sıralı tutulduğu için

Madde 2. Aşağıdaki program ne yazdırır?

record = ("Ada", [70, 80])
record[1].append(90)
print(record)
  • A. ('Ada', [70, 80], 90)
  • B. TypeError; demet değiştirilemez
  • C. ('Ada', [70, 80]); demet içindeki liste kopyalanır
  • D. AttributeError; demet elemanlarında metot çağrılamaz
  • E. ('Ada', [70, 80, 90]); demetin elemanları değişmedi, içindeki listenin durumu değişti

Madde 3. Aşağıdaki program ne yazdırır?

first = [10, 20]
second = first
second.append(30)

print(first)
print(second)
  • A. Her iki satırda da [10, 20, 30]
  • B. [10, 20, 30] ve [10, 20]
  • C. [10, 20] ve [10, 20, 30]
  • D. [10, 20, 30] ve [30]
  • E. Hata verir; bir listeyi iki ada bağlamak yasaktır

Madde 4. Aşağıdaki program ne yazdırır?

def ekle(liste):
    liste.append(99)

sayilar = [1, 2]
ekle(sayilar)
print(sayilar)
  • A. [1, 2]; fonksiyon kendi kopyası üzerinde çalışır
  • B. [1, 2, 99]; fonksiyona liste kopyalanmaz, aynı nesnenin referansı geçer
  • C. None
  • D. Hata verir; fonksiyon dışındaki liste değiştirilemez
  • E. [99]

Madde 5. Aşağıdaki program ne yazdırır?

a = [1, 2]
b = [1, 2]

print(a == b)
print(a is b)
  • A. False ve False
  • B. Hata verir; listelerde is kullanılamaz
  • C. True ve False
  • D. True ve True
  • E. False ve True

Madde 6. Aşağıdaki program ne yazdırır?

original = [10, 20]
copy = original.copy()
copy.append(30)

print(original)
print(copy)
  • A. Hata verir; copy yerleşik bir addır ve değişken olarak kullanılamaz
  • B. [10, 20] ve [30]
  • C. [10, 20, 30] ve [10, 20]
  • D. [10, 20] ve [10, 20, 30]
  • E. Her iki satırda da [10, 20, 30]

Madde 7. Aşağıdaki program ne yazdırır?

original = [[1, 2], [3, 4]]
copy = original.copy()
copy[0].append(99)

print(original)
  • A. [[1, 2], [3, 4]]; kopya tümüyle bağımsızdır
  • B. TypeError; kopyalanmış listenin elemanları değiştirilemez
  • C. [[1, 2], [3, 4], 99]
  • D. [[99], [3, 4]]
  • E. [[1, 2, 99], [3, 4]]; sığ kopya dış listeyi ayırır, içteki nesneler hâlâ paylaşılır

Madde 8. stocks = {"P100": 2, "P200": 0} iken for x in stocks: döngüsünde x neyi alır?

  • A. Anahtarları; değer de gerekiyorsa .items() kullanılmalıdır
  • B. Anahtar ve değerleri sırayla tek tek
  • C. (anahtar, değer) çiftlerini
  • D. Hata verir; sözlük üzerinde doğrudan dolaşılamaz
  • E. Değerleri

Madde 9. Aşağıdaki program ne yazdırır?

scores = [80, 60, 90]
ordered = sorted(scores)
print(scores)
print(ordered)
  • A. [60, 80, 90] ve None
  • B. [80, 60, 90] ve [60, 80, 90]
  • C. Hata verir; sorted bir değişkene atanamaz
  • D. Her iki satırda da [80, 60, 90]
  • E. Her iki satırda da [60, 80, 90]

Madde 10. Aşağıdaki program ne yazdırır?

scores = [80, 60, 90]
result = scores.sort()
print(result)
  • A. Hata verir; sort() dönüş değeri bir değişkene atanamaz
  • B. [80, 60, 90]
  • C. None; list.sort() listeyi yerinde sıralar ve değer döndürmez
  • D. [60, 80, 90]
  • E. True

Madde 1 — Doğru: D. Küme aynı değeri bir kez tutar; sıra önemli değilse en doğrudan seçimdir.

  • A yanlış: Değişmezlik tekrar içermediği anlamına gelmez; ("a", "a") geçerlidir.
  • B yanlış: Liste aynı değeri birden çok kez tutar; benzersizliği elle sağlamak gerekir.
  • C yanlış: Metin bir koleksiyon kabı değildir; kelimeleri ayrı ayrı yönetmez.
  • E yanlış: Sözlük kullanılabilir ama değer tarafı boşa gider; yalnız üyelik için küme yeterlidir.

Madde 2 — Doğru: E. Demetin değişmezliği eleman bağlarına aittir. record[1] hâlâ aynı listeyi gösterir; o listenin içeriği değiştirilebilir.

  • A yanlış: append demete değil, demetin içindeki listeye uygulanır.
  • B yanlış: Hata ancak record[1] = ... gibi bağı yeniden atamada çıkar; burada bağ değişmiyor.
  • C yanlış: Demet elemanlarını kopyalamaz; nesnelere referans tutar.
  • D yanlış: Eleman bir listedir ve kendi metotlarına sahiptir.

Madde 3 — Doğru: A. second = first yeni bir liste oluşturmaz; iki ad aynı liste nesnesini gösterir. Bir addan yapılan değişiklik diğerinden de görülür.

  • B yanlış: append çağrısı second üzerinden yapıldı; iki ad zaten aynı nesneyi gösteriyor.
  • C yanlış: Atama kopya üretseydi böyle olurdu; atama yalnız yeni bir ad bağlar.
  • D yanlış: append listeyi sıfırlamaz; sonuna ekler.
  • E yanlış: Aynı nesneye birden çok ad bağlamak geçerli ve yaygındır.

Madde 4 — Doğru: B. Argüman aktarımı nesneyi kopyalamaz. Fonksiyon içindeki liste ile dışarıdaki sayilar aynı nesneyi gösterir.

  • A yanlış: Python argümanı kopyalamaz; bu C’deki değer kopyası sezgisidir.
  • C yanlış: Yazdırılan sayilar adıdır; fonksiyonun dönüş değeri değil.
  • D yanlış: Böyle bir kısıt yoktur; yan etki tam olarak bu yüzden tasarım kararıdır.
  • E yanlış: append listeyi sıfırlamaz.

Madde 5 — Doğru: C. İçerikleri eşittir ama bunlar iki ayrı liste nesnesidir. == değeri, is kimliği sorgular.

  • A yanlış: Listelerde == eleman eleman karşılaştırır ve eşitlik doğrudur.
  • B yanlış: is her nesne için geçerlidir.
  • D yanlış: Eşit içerik aynı nesne olmayı gerektirmez.
  • E yanlış: Sonuçlar ters yazılmış.

Madde 6 — Doğru: D. copy() yeni bir liste nesnesi üretir; iki ad artık ayrı nesneleri gösterir.

  • A yanlış: copy anahtar sözcük değildir; ad olarak kullanılabilir.
  • B yanlış: Kopya kaynağın elemanlarıyla başlar; boş değildir.
  • C yanlış: Ekleme copy üzerinden yapıldı; değişen odur.
  • E yanlış: Bu, copy = original yazılsaydı çıkardı; copy() bağı ayırır.

Madde 7 — Doğru: E. copy() yalnız bir düzey kopyalar. copy[0] ile original[0] aynı iç listeyi gösterir.

  • A yanlış: Bu ancak derin kopya alınsaydı doğru olurdu.
  • B yanlış: Kopyalama iç nesneleri dondurmaz.
  • C yanlış: Ekleme dış listeye değil, ilk iç listeye yapılır.
  • D yanlış: append iç listeyi sıfırlamaz; sonuna ekler.

Madde 8 — Doğru: A. Sözlük üzerinde doğrudan dolaşmak anahtarları verir. (anahtar, değer) çiftleri için .items() gerekir.

  • B yanlış: Her tur tek bir anahtar verir; anahtar ve değer dönüşümlü gelmez.
  • C yanlış: Bu .items() davranışıdır.
  • D yanlış: Sözlük dolaşılabilir bir yapıdır.
  • E yanlış: Değerler için .values() yazılmalıdır.

Madde 9 — Doğru: B. sorted() yeni bir liste döndürür ve kaynağı değiştirmez.

  • A yanlış: None döndüren list.sort()tur; sorted() yeni liste verir.
  • C yanlış: Dönüş değeri normal bir listedir ve atanabilir.
  • D yanlış: ordered sıralı sonucu tutar.
  • E yanlış: Bu scores.sort() çağrılsaydı olurdu; sorted() yerinde değiştirmez.

Madde 10 — Doğru: C. Yerinde çalışan metotlar sonucu döndürmez. Sıralı liste scores adındadır.

  • A yanlış: Atama geçerlidir; atanan değer Nonedır.
  • B yanlış: Sıralama gerçekleşir; ancak dönüş değeri liste değildir.
  • D yanlış: Bu sorted(scores) sonucudur.
  • E yanlış: Başarı bayrağı döndürmez.

Tek sayfa özet

  • Python koleksiyonları farklı kullanım amaçları olan nesnelerdir; bu hafta hepsini aynı derinlikte ezberlemek yerine doğru kullanım kalıplarını öğreniyoruz.
  • Değiştirilebilir nesnelerde iki değişken aynı nesneyi gösterebilir.
  • is kimlik, == eşitlik sorusudur.
  • .copy() dış koleksiyonu ayırır; içteki nesneler paylaşılabilir.
  • Sözlükte .items() anahtar ve değerle birlikte dolaşmanın temel yoludur.
  • Sözlük anahtarları hashlenebilir olmalıdır.
  • sorted() yeni liste üretir; .sort() listeyi yerinde değiştirir.
  • Dağınık sözlük güncellemeleri, ileride sınıf ve metot tasarımının neden gerekli olduğunu gösterecektir.

Bu bölümün kazanımları

Bu bölümü bitiren öğrenci:

  • list, tuple, dict ve set arasından probleme uygun koleksiyonu seçer.
  • Demetin değişmezliğinin eleman bağlarına ait olduğunu, içindeki nesnenin durumunu kapsamadığını açıklar.
  • b = a ile iki adın aynı nesneyi gösterdiğini tanır ve bir yerdeki değişikliği diğerinden okur.
  • is ile == sorularını birbirinden ayırır.
  • copy() ile bağımsız kopya üretir ve sığ kopyanın sınırını belirler.
  • Sözlükte .keys(), .values() ve .items() görünümlerini yerinde kullanır.
  • sorted() ile .sort() arasındaki dönüş değeri ve yerinde değiştirme farkını gösterir.
Back to top