---
title: Demetler
source: 'https://academia.sh/tr/kurslar/python-veri-yapilari/demetler'
course: 'Veri Yapıları ve Fonksiyonel Araçlar'
language: tr
updated: '2026-08-17T18:10:25+00:00'
license: 'CC BY-SA 4.0'
---

# Demetler

Altı işlemden üçü demette istisnayla düşer ama iç öğeyi değiştiren işlem demette de geçer; değişmezlik bir katman derinliğindedir ve karşılığında kabın kazandığı yetki, beş adayın üçünde görüldüğü gibi anahtar olabilmektir.

Önceki dersin bütün ölçümleri listenin değiştirilebilir olmasına dayanıyordu: yuva
eklenebiliyor, silinebiliyor, yeniden dizilebiliyordu. Var edilen nesne sayısı çoğu biçimde
sıfırdı, çünkü liste yalnız yuvaları düzenliyordu.

Bu ders aynı yuvaları **değişmez** bir kapta yeniler. **Demet (tuple)** de sıralı bir
yuva dizisidir, ama kurulduktan sonra yuvaları yeniden yazılamaz. Soru iki parçalıdır ve
ikisi de sayılabilir: değişmezlik **hangi işlemi** gerçekten imkânsız kılıyor, ve bu
imkânsızlığın karşılığında kap **hangi yetkiyi** kazanıyor?

## Değişmezlik Neyi Kapatır

Değişmezlik kavramının kendisi bu kursun konusu değildir. Programlama Temelleri kursunda
değiştirilebilir ile değiştirilemez nesnenin ayrımı kuruldu; Yazılım Tasarımı ve Mimari
İlkeler kursu değişmezliği paylaşılan durumu ortadan kaldıran bir **tasarım tekniği** olarak
ele aldı. İkisi de burada tekrarlanmaz. Burada ölçülen şey daha dar ve daha somut: aynı
işlem dizisi iki kapta çalıştırıldığında **hangi satırlar geçiyor, hangileri istisnayla
düşüyor.**

Ayrımın nerede durduğunu baştan söylemek gerekir, çünkü ölçüm tam oraya bakacak. Bir demet
**kendi yuvalarını** korur. Yuvaların gösterdiği nesnelerin içine karışmaz ve karışamaz —
onlar ayrı nesnelerdir ve kendi kurallarına tabidir. Demetin verdiği güvence bu yüzden
"içindekiler değişmez" değil, **"hangi nesneye baktığım değişmez"** güvencesidir.

- **KL13** — Altı işlem her iki kapta da **aynı sırayla** ve her seferinde tazeden kurulmuş
  bir kapla denenir; kaplar aynı değerlerden üretilir.
- **KL14** — Sonuç sütunu üç değerden birini alır: işlem geçtiyse sonucun **aynı kap** mı
  yoksa **yeni kap** mı olduğu, geçmediyse düşen istisnanın **sınıf adı**.
- **KL15** — "Aynı kap" kararı işlemden önce tutulan bağla `is` karşılaştırmasıdır.
- **KL16** — Sıralama bir **anahtar işleviyle** yapılır; öğe sınıfına karşılaştırma yöntemi
  eklenmez ve sayma düzeni değişmez.
- **KL17** — İç öğeyi değiştiren satır kabın kendisine hiç dokunmaz; yalnız bir yuvanın
  gösterdiği nesnenin alanına yazar.

```python
"""Ayni alti islem listede ve demette: degismezlik neyi imkansiz kiliyor."""

SAYAC = {"uretilen": 0}


class Oge:
    def __init__(self, deger):
        SAYAC["uretilen"] += 1
        self.deger = deger

    def __repr__(self):
        return f"Oge({self.deger})"


def sifirla():
    SAYAC["uretilen"] = 0


def uretilen():
    return SAYAC["uretilen"]


def deger(o):
    return o.deger


HAVUZ = [Oge(i) for i in (3, 1, 4)]


def yerine_yaz(k):
    k[0] = Oge(9)
    return k


def sona_ekle(k):
    k.append(Oge(9))
    return k


def sil(k):
    del k[0]
    return k


def yerinde_topla(k):
    k += type(k)((Oge(9),))
    return k


def ic_ogeyi_degistir(k):
    k[0].deger = 9
    return k


def sirala(k):
    return sorted(k, key=deger)


ISLEMLER = (("k[0] = yeni", yerine_yaz), ("k.append(yeni)", sona_ekle),
            ("del k[0]", sil), ("k += (yeni,)", yerinde_topla),
            ("k[0].deger = 9", ic_ogeyi_degistir), ("sorted(k, ...)", sirala))

print(f"{'işlem':<18s}{'listede':<16s}{'demette'}")
for ad, islem in ISLEMLER:
    satir = []
    for tip in (list, tuple):
        k = tip(Oge(o.deger) for o in HAVUZ)
        once = k
        try:
            sonuc = islem(k)
            satir.append("aynı kap" if sonuc is once else "yeni kap")
        except Exception as e:
            satir.append(type(e).__name__)
    print(f"{ad:<18s}{satir[0]:<16s}{satir[1]}")

print()
demet = tuple(HAVUZ)
sifirla()
buyuk = demet + (Oge(9),)
print(f"demete ekleme: var edilen {uretilen()} | eski yuva {len(demet)} -> "
      f"yeni yuva {len(buyuk)}")
print(f"buyuk is demet -> {buyuk is demet} | "
      f"buyuk[0] is demet[0] -> {buyuk[0] is demet[0]}")

print()
print(f"demet[0].deger okuma: {demet[0].deger}")
demet[0].deger = 9
print(f"iç öğe değiştirildikten sonra: {demet[0].deger} | "
      f"demet[0] is HAVUZ[0] -> {demet[0] is HAVUZ[0]}")
```

```
işlem             listede         demette
k[0] = yeni       aynı kap        TypeError
k.append(yeni)    aynı kap        AttributeError
del k[0]          aynı kap        TypeError
k += (yeni,)      aynı kap        yeni kap
k[0].deger = 9    aynı kap        aynı kap
sorted(k, ...)    yeni kap        yeni kap

demete ekleme: var edilen 1 | eski yuva 3 -> yeni yuva 4
buyuk is demet -> False | buyuk[0] is demet[0] -> True

demet[0].deger okuma: 3
iç öğe değiştirildikten sonra: 9 | demet[0] is HAVUZ[0] -> True
```

## Üç Satır Düşüyor, Üç Satır Geçiyor

Altı işlemin üçü demette istisnayla düşüyor ve üçü geçiyor. Düşen üçü aynı şeyi denedi:
**var olan bir yuvayı yeniden yazmak, yuva eklemek ya da yuva silmek.** Düşme biçimleri
ayrı. Yuvaya yazmak ve yuva silmek `TypeError` veriyor — bu iki yazım demette de bir
anlama gelir, ama demet o anlamı desteklemiyor. Sona ekleme ise `AttributeError` veriyor:
demette `append` diye bir yöntem **yoktur**. Birincisi "yapamam", ikincisi "böyle bir şey
bilmiyorum" der.

Geçen üç satırın ikisi zaten kabı değiştirmiyordu. `sorted` her iki kapta da **yeni kap**
veriyor; zaten hep yeni bir liste döndürür ve kaynağa dokunmaz. `k += (yeni,)` satırı ise
ayrımın tam ortasında duruyor: listede **aynı kap**, demette **yeni kap**. Yazım aynı, sonuç
aynı görünüyor, ama biri var olan kabı uzatıyor, öbürü yeni bir kap kurup adı ona bağlıyor.
Demet değişmez olduğu için yerinde büyütme demette bir uzatma değil, bir **yeniden
kurmadır**.

Ortadaki sayılar bu yeniden kurmanın faturasını veriyor: var edilen **1**, ve o bir tane de
eklenen öğenin kendisi. Kap büyüyor — üç yuvadan dört yuvaya — ama kabın içindeki eski üç
nesne yeniden üretilmiyor. `buyuk is demet` **False**, yani kap gerçekten yeni; ama
`buyuk[0] is demet[0]` **True**, yani öğe eski. Bir demeti bin kez bir öğe ekleyerek
büyütmek, bin kap kurmak demektir; içindeki nesneleri bin kez kopyalamak demek değildir.

Son iki satır bu dersin en kritik ölçümüdür. `k[0].deger = 9` demette **geçiyor** — hem de
hiçbir uyarı vermeden. Demet kendi yuvasını korudu: yuva hâlâ aynı nesneye bakıyor ve
`demet[0] is HAVUZ[0]` bunu doğruluyor. Ama o nesnenin **içi** değişti; okunan değer **3**
iken **9** oldu. Demek ki **değişmezlik bir katman derinliğindedir**: kabın verdiği güvence
yuvaların hangi nesneyi gösterdiğiyle sınırlıdır, o nesnelerin durumuyla değil.

## Değişmezliğin Karşılığı

Kapatılan üç işlemin karşılığında bir yetki açılır. Bir nesnenin **karmalanabilir** olması,
ondan sabit bir **karma değeri** hesaplanabilmesi demektir; bu değer nesnenin ömrü boyunca
değişmemelidir. Yuvaları yeniden yazılabilen bir kapta böyle bir söz verilemez, çünkü kap
değiştiğinde karma değeri de değişirdi ve nesne konduğu yerde kaybolurdu. Demet bu sözü verebilir —
ama yalnız içindekiler de verebiliyorsa.

- **KL18** — Karmalanabilirlik doğrudan sınanır: karma değeri alma denenir ve düşen istisnanın
  sınıf adı yazılır. **Karma değeri basılmaz**; ölçülen şey değerin kendisi değil, alınıp
  alınamadığıdır.
- **KL19** — Anahtar olabilme ayrı bir sütundur ve tek girdilik bir eşleme kurularak
  sınanır; iki sütun birbirini doğrular.
- **KL20** — Çoklu dönüş ölçümünde işlev **var olan** öğeleri döndürür; böylece sayılan şey
  yalnız dönüşün ve çözmenin kendi maliyetidir.
- **KL21** — Çözmede var edilen sayısı, dönüşten sonraki sayaçtan dönüşteki sayı düşülerek
  bulunur; iki aşama ayrı ayrı okunur.

```python
"""Demetin kazandigi yetki: anahtar olabilmek ve coklu donus degeri tasimak."""

SAYAC = {"uretilen": 0}


class Oge:
    def __init__(self, deger):
        SAYAC["uretilen"] += 1
        self.deger = deger

    def __repr__(self):
        return f"Oge({self.deger})"


def sifirla():
    SAYAC["uretilen"] = 0


def uretilen():
    return SAYAC["uretilen"]


ADAYLAR = (("(2031, 7)", (2031, 7)), ("[2031, 7]", [2031, 7]),
           ("((2031, 7), (2032, 1))", ((2031, 7), (2032, 1))),
           ("(2031, [7])", (2031, [7])), ("'kuzey'", "kuzey"))

print(f"{'aday':<24s}{'karmalanabilir':<16s}{'anahtar olabilir'}")
for ad, x in ADAYLAR:
    try:
        hash(x)
        h = "evet"
    except TypeError as e:
        h = type(e).__name__
    try:
        {x: 0}
        a = "evet"
    except TypeError as e:
        a = type(e).__name__
    print(f"{ad:<24s}{h:<16s}{a}")

KAYIT = {(2031, 7): "yamac", (2031, 8): "kuzey", (2032, 1): "ozet"}
print()
print(f"demet anahtarlı sözlük: {len(KAYIT)} girdi | "
      f"KAYIT[(2031, 8)] -> {KAYIT[(2031, 8)]!r}")

HAVUZ = [Oge(i) for i in (3, 1, 4)]


def uclu():
    return HAVUZ[0], HAVUZ[1], HAVUZ[2]


sifirla()
sonuc = uclu()
donus_uretimi = uretilen()
a, b, c = sonuc
cozme_uretimi = uretilen()
print()
print(f"dönüş kabının tipi {type(sonuc).__name__} | yuva {len(sonuc)} | "
      f"dönüşte var edilen {donus_uretimi} | çözmede var edilen "
      f"{cozme_uretimi - donus_uretimi}")
print(f"a is HAVUZ[0] -> {a is HAVUZ[0]} | c is HAVUZ[2] -> {c is HAVUZ[2]}")

sifirla()
x, y = HAVUZ[0], HAVUZ[1]
x, y = y, x
print(f"iki adı takas etmek: var edilen {uretilen()} | "
      f"x is HAVUZ[1] -> {x is HAVUZ[1]}")

sifirla()
bas, *orta = HAVUZ
print(f"yıldızlı çözme: var edilen {uretilen()} | orta bir "
      f"{type(orta).__name__} ve {len(orta)} yuva | "
      f"orta[0] is HAVUZ[1] -> {orta[0] is HAVUZ[1]}")
```

```
aday                    karmalanabilir  anahtar olabilir
(2031, 7)               evet            evet
[2031, 7]               TypeError       TypeError
((2031, 7), (2032, 1))  evet            evet
(2031, [7])             TypeError       TypeError
'kuzey'                 evet            evet

demet anahtarlı sözlük: 3 girdi | KAYIT[(2031, 8)] -> 'kuzey'

dönüş kabının tipi tuple | yuva 3 | dönüşte var edilen 0 | çözmede var edilen 0
a is HAVUZ[0] -> True | c is HAVUZ[2] -> True
iki adı takas etmek: var edilen 0 | x is HAVUZ[1] -> True
yıldızlı çözme: var edilen 0 | orta bir list ve 2 yuva | orta[0] is HAVUZ[1] -> True
```
## Beş Adayın Üçü Geçiyor

Tablo karmalanabilirliğin kaba değil, **kabın bütününe** baktığını gösteriyor. Sayı çifti
geçiyor, iç içe demet de geçiyor — çünkü içindeki her şey de karmalanabilir. Liste düşüyor;
bu beklenirdi. Asıl satır dördüncüsüdür: **bir liste taşıyan demet de düşüyor.** Kabın
kendisi değişmez olduğu hâlde. Bir demetin karma değeri içindekilerin karma
değerlerinden hesaplanır, ve içlerinden biri karma değeri veremiyorsa demet de veremez.

Bu, bir önceki bölümün bulgusunun ikinci yüzüdür. Orada değişmezliğin bir katman derinliğinde
olduğunu gördük; burada dilin bunu **bildiği** görülüyor. Demet, güvenceyi ancak
içindekilerin de verdiği kadar verebilir ve veremediğinde anahtar olma yetkisini kaybeder.
İki sütunun aynı yanıtı vermesi rastlantı değildir: eşlemeye anahtar olma koşulu tam olarak
karma değeri alınabilmesidir.

Alt bloktaki üç ölçüm demetin görünmeyen kullanımını sayıyor. Bir işlev virgülle ayrılmış
üç değer döndürdüğünde ortaya bir **demet** çıkar — bu, ayrı bir sözdizim değil, demet
kurmanın parantezsiz yazımıdır. Dönüşte var edilen **0**, çözmede var edilen **0**. İşlev
üç nesneyi paketleyip verdi, atama üç adı o nesnelere bağladı; hiçbir aşamada kopya
çıkarılmadı ve `a is HAVUZ[0]` bunu doğruluyor.

İki adı takas eden satır aynı düzeneğin en kısa hâlidir: sağ taraf bir demet kurar, sol
taraf onu çözer, var edilen öğe **0**. Yıldızlı çözme ise bir ayrıntı ekliyor — artan
yuvaları toplayan kap bir demet değil, bir **listedir**, ve o listenin yuvaları yine eski
nesnelere gidiyor. Çoklu dönüş değeri bu yüzden ucuz bir yazımdır: taşınan şey nesneler
değil, onlara giden bağlardır.

## Anahtar Neye Göre Bulunur

Bir demetin anahtar olabilmesi ölçüldü; anahtarın **nasıl bulunduğu** ölçülmedi. Bu ayrım
önemlidir, çünkü önceki dersin silme ölçümünde eşitliğe bakan bir yöntem kimliğe düşmüştü.
Eşlemede öyle bir düşüş yoktur: anahtar her zaman karma değeri ve eşitlikle aranır, kimlikle değil.

- **KL22** — Aranan anahtar iki değişkenden **çalışma anında** kurulur; eşlemenin içindeki
  anahtar ise kaynak metindeki yazımdan gelir. İkisinin ayrı nesne olduğu `is` ile sınanır.
- **KL23** — Karma değerlerinin **eşitliği** karşılaştırılır; değerlerin kendisi basılmaz.
- **KL24** — Aynı değerleri taşıyan üç demet bir döngüde ayrı ayrı kurulur; ikisi eşittir ve
  eşlemede kaç girdi kaldığı sayılır.

```python
"""Anahtar kimlikle degil esitlikle bulunur; kabin tipi esitlige girer."""

KAYIT = {(2031, 7): "yamac", (2031, 8): "kuzey"}
YIL, AY = 2031, 7
ARANAN = (YIL, AY)   # calisma aninda kurulur, sabit degildir
ILK = next(iter(KAYIT))

print(f"aranan is sözlükteki anahtar -> {ARANAN is ILK}")
print(f"aranan == sözlükteki anahtar -> {ARANAN == ILK}")
print(f"karma değerleri eşit -> {hash(ARANAN) == hash(ILK)}")
print(f"KAYIT[aranan] -> {KAYIT[ARANAN]!r}")

print()
print(f"(2031, 7) == [2031, 7] -> {(2031, 7) == [2031, 7]}")
print(f"(2031, 7) == (2031, 7, None) -> {(2031, 7) == (2031, 7, None)}")
for aday in ((2031, 7), [2031, 7]):
    try:
        var = aday in KAYIT
    except TypeError as e:
        var = type(e).__name__
    print(f"{str(aday):<12s} in KAYIT -> {var}")

print()
DEMETLER = [(2031, a) for a in (7, 8, 7)]
print(f"üç demet kuruldu | ayrı nesne mi: "
      f"{DEMETLER[0] is DEMETLER[2]} | eşit mi: {DEMETLER[0] == DEMETLER[2]}")
KUME = {d: i for i, d in enumerate(DEMETLER)}
print(f"üçü de anahtar yapıldı, eşlemede kalan girdi: {len(KUME)}")
```

```
aranan is sözlükteki anahtar -> False
aranan == sözlükteki anahtar -> True
karma değerleri eşit -> True
KAYIT[aranan] -> 'yamac'

(2031, 7) == [2031, 7] -> False
(2031, 7) == (2031, 7, None) -> False
(2031, 7)    in KAYIT -> True
[2031, 7]    in KAYIT -> TypeError

üç demet kuruldu | ayrı nesne mi: False | eşit mi: True
üçü de anahtar yapıldı, eşlemede kalan girdi: 2
```

İlk dört satır aranan kuralı veriyor: nesne **ayrı**, değer **eşit**, özetler **eşit**, ve
arama başarılı. Anahtarı bulan şey kimlik değildir. Bu, demetin ucuz bir anahtar olmasının
nedenidir — anahtarı taşımak gerekmez, aynı değerlerden yenisini kurmak yeter.

Aradaki satırlar eşitliğin **kap tipini de kapsadığını** gösteriyor. Aynı iki sayıyı taşıyan
liste demede eşit değildir, ve tipi kaldırıp yalnız içeriğe bakan bir kural yoktur. Uzunluğu
farklı bir demet de eşit değildir. Üyelik sınamasında ayrım daha da serttir: liste yalnız
eşit sayılmakla kalmaz, `TypeError` ile düşer — çünkü aranmadan önce karma değeri alınması gerekir
ve o adım hiç gerçekleşmez.

Son iki satır eşitliğin sonucunu somutlaştırıyor. Üç demet ayrı ayrı kuruldu; birinci ile
üçüncü ayrı nesne ama eşit. Üçü de anahtar yapıldığında eşlemede **2** girdi kalıyor: eşit
iki anahtar aynı yere düştü ve ikincisi birincinin değerini ezdi. Kabın kimliği hiçbir yerde
işe karışmadı.

## Özet

- Değişmezlik üç işlemi kapatır: yuvaya yazmak, yuva silmek ve yuva eklemek. İlk ikisi
  `TypeError`, sonuncusu `AttributeError` ile düşer — biri "yapamam", öbürü "bilmiyorum" der.
- Demette `k += (yeni,)` bir uzatma değil **yeniden kurmadır**: kap yenidir
  (`buyuk is demet` → False) ama öğeler eskidir (`buyuk[0] is demet[0]` → True) ve var
  edilen **1**'dir.
- Değişmezlik **bir katman derinliğindedir**: `k[0].deger = 9` demette de geçer, çünkü demet
  yuvasını korur, yuvanın gösterdiği nesnenin içini değil.
- Kabın kazandığı yetki anahtar olabilmektir ve bu yetki **içindekilere bağlıdır**: beş
  adaydan üçü geçer, liste taşıyan demet kabın kendisi değişmez olduğu hâlde düşer.
- Çoklu dönüş değeri bir demettir ve **0** öğe var eder; çözme de **0** var eder, çünkü
  taşınan şey nesneler değil onlara giden bağlardır.

## Sonraki Adım

Demet anahtar **olabildi**; ama anahtarı alıp değere ulaştıran kabın kendisi henüz
ölçülmedi. Sonraki ders eşlemeye bakar ve kursun dördüncü okumasının ilk yarısını öder:
aynı iki yüz öğe bir listede ve bir kümede arandığında kaç karşılaştırma yapılır? Veri aynı,
öğeler aynı, değişen tek şey onları hangi kapta tuttuğumuz. Aynı ders bir ikinci soruyu daha
sorar: bir sözlüğün anahtarlarını istediğimizde elimize geçen şey bir kopya mı, yoksa
sözlüğe bakmayı sürdüren bir pencere mi?
