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

# Listeler

Liste öğeleri değil onlara giden bağları tutar; bin öğe koymak 1000 nesne var eder ama listeyi ikinci bir ada bağlamak 0, aynı öğeyi beş kez eklemek 1 var eder ve sekiz büyütme biçiminden yalnız üçü yeni kap kurar.

Python Temelleri kursu on altı derste tek bir iddiayı ölçtü: sözdizim bir kısaltmadır ve her
biçim adı belli bir özel yöntemi çağırır. Kapanışında bıraktığı ayrım şuydu: **protokolü
kullanmakla protokolü yazmak ayrı şeylerdir.** Orada ölçülen nesne kurgu bir nesneydi;
hiçbir yerleşik koleksiyondan inmiyordu ve `for` içine girebilmesinin tek gerekçesi ilgili
yöntemleri tanımlamış olmasıydı.

Bu kursta aynı protokolleri **dilin kendi kapları** taşır. Onlar da aynı yöntemleri
tanımlar, ama artık bir gösteri için değil, gerçek veri için. Ve gerçek veriyle birlikte
soru da değişir: bir kabın **ne yapabildiği** değil, **neye mal olduğu**. Bu dersin sorusu
budur — bir liste kurulduğunda ortaya kaç nesne çıkar, bunların kaçı listenin kendi ürünüdür
ve liste onların kaçını canlı tutar?

## Kap Neyi Tutar

Bir **liste (list)** öğelerini içine **almaz**. Sıralı bir yuva dizisi tutar ve her yuva
bir nesneye giden bağdır. Bu ayrım Python'a özgü değil, nesne modelinin doğrudan sonucudur:
bir ada değer bağlamak nesneyi kopyalamaz, ona bir ad daha verir. Programlama Temelleri
kursunda atamanın bir **bağlama** olduğu, `is` ile `==` ayrımı ve takma ad kavramı zaten
kuruldu ve burada tekrarlanmaz. Yeni olan şey, aynı bağlamanın **bir ada değil bir yuvaya**
yapılabilmesidir.

Sonucu şudur: listeyi büyüten her işlem yuva sayısını artırır, ama nesne sayısını
artırmayabilir. Aynı nesne beş yuvada durabilir; o zaman liste beş uzunluktadır ve içinde
tek bir nesne vardır.

Sıralı kapların kendi yapı kuramı — dizi, dinamik dizi, bağlı liste, büyüme oranı — Veri
Yapıları kursunda kuruldu ve burada tekrarlanmaz. Orada **düzenek** kuruldu; burada
Python'un o düzeneği hangi kapla verdiği ve bunun **kaç nesneye** mal olduğu ölçülüyor.

## Ortak Kurgu: Her Üretimini Sayan Öge

Ölçüm için tek bir sınıf yeter. `Oge`, her üretiminde ortak bir sayacı bir artırır; başka
hiçbir şey yapmaz. Bir işlemin kaç nesne var ettiğini bilmek için sayacı sıfırlamak, işlemi
yapmak ve sayacı okumak yeter. Kâhin kurgunun kendisidir: üretimi nesne kendi saydığı için,
paylaşımı `is` gösterdiği için biliriz. Kurs boyunca üç sayı ayrı ayrı yazılır — **var
edilen** nesne, **tutulan** yuva ve bunların kaçının **ayrı** nesneye gittiği.

Nesnelerin kimliği hiçbir yerde sayı olarak basılmaz. İki yuvanın aynı nesneye gidip
gitmediği yalnız `is` ile sınanır; ayrı nesne sayısı da bu sınamaların toplamıdır.

- **KL1** — Sayaç yalnız `Oge` üretimini sayar; listenin, demetin ya da başka bir kabın
  kendisi sayılmaz. Kap sayısı ayrıca, kimlik sınamasıyla okunur.
- **KL2** — Her satırda sayaç işlemden **hemen önce** sıfırlanır; ölçülen şey yalnız o
  satırın var ettiğidir.
- **KL3** — Ayrı nesne sayısı `is` karşılaştırmalarıyla bulunur; hiçbir kimlik değeri
  basılmaz ve sayıya bakılarak kimlik hakkında başka bir çıkarım yapılmaz.
- **KL4** — Bin öğelik ölçüm listenin büyüme davranışını değil, yalnız var edilen nesne
  sayısını sınar; büyüme sınıfı Algoritmalar kursunun konusudur ve burada ölçülmez.
- **KL5** — Çarpma ölçümünde çarpılan liste **tek öğeliktir**; böylece çarpımın yuva
  çoğaltmakla nesne çoğaltmak arasındaki farkı tek başına görünür.

```python
"""Liste bir kaptir: yuvalari tutar, ogeleri kendisi var etmez."""

SAYAC = {"uretilen": 0}


class Oge:
    """Her uretimi sayan 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 ayri(kap):
    """Kimlikce ayri nesne sayisi. Kimlik `is` ile sinanir, sayisi basilmaz."""
    benzersiz = []
    for x in kap:
        if not any(x is y for y in benzersiz):
            benzersiz.append(x)
    return len(benzersiz)


N = 1000

print(f"{'işlem':<32s}{'var edilen':>11s}{'yuva':>6s}{'ayrı nesne':>12s}")

sifirla()
liste = []
for i in range(N):
    liste.append(Oge(i))
print(f"{'bin öğeyi listeye koymak':<32s}{uretilen():>11d}{len(liste):>6d}"
      f"{ayri(liste):>12d}")

sifirla()
takma = liste
print(f"{'listeyi ikinci bir ada bağlamak':<32s}{uretilen():>11d}"
      f"{len(takma):>6d}{ayri(takma):>12d}")

sifirla()
tek = Oge(0)
elle = [tek, tek, tek, tek, tek]
print(f"{'aynı öğeyi beş kez eklemek':<32s}{uretilen():>11d}{len(elle):>6d}"
      f"{ayri(elle):>12d}")

sifirla()
carpim = [tek] * 5
print(f"{'tek öğelik listeyi beşle çarpmak':<32s}{uretilen():>11d}"
      f"{len(carpim):>6d}{ayri(carpim):>12d}")

print()
print(f"takma is liste -> {takma is liste} | "
      f"carpim[0] is carpim[4] -> {carpim[0] is carpim[4]} | "
      f"carpim[0] is tek -> {carpim[0] is tek}")
print(f"liste[0] is liste[1] -> {liste[0] is liste[1]}")
```

```
işlem                            var edilen  yuva  ayrı nesne
bin öğeyi listeye koymak               1000  1000        1000
listeyi ikinci bir ada bağlamak           0  1000        1000
aynı öğeyi beş kez eklemek                1     5           1
tek öğelik listeyi beşle çarpmak          0     5           1

takma is liste -> True | carpim[0] is carpim[4] -> True | carpim[0] is tek -> True
liste[0] is liste[1] -> False
```

## Dört Satırın Söylediği

Birinci satır beklendiği gibi: bin öğe koymak **1000** nesne var eder, **1000** yuva tutar
ve bunların hepsi ayrı nesnedir. Ama bu 1000 nesneyi var eden şey **liste değildir**. Onları
`Oge(i)` çağrısı üretti; liste yalnız yuvaları tuttu. Aynı bin nesne hiç listeye konmadan da
var edilebilirdi ve sayaç yine 1000 gösterirdi.

İkinci satır bunun kanıtıdır: aynı listeyi ikinci bir ada bağlamak **0** nesne var eder.
Yuva sayısı değişmez, ayrı nesne sayısı değişmez, sadece nesneye giden ad sayısı bir artar —
ve `takma is liste` bunu doğrular. Bin öğelik bir listeyi bir işleve geçirmek de aynı şeydir
ve maliyeti aynıdır: **sıfır**.

Üçüncü satır ayrımı tersinden gösteriyor. Beş yuva var, ama var edilen nesne **1** ve ayrı
nesne **1**. Liste beş uzunlukta, içinde tek bir nesne. Dördüncü satır aynı sonucu
sözdizimin kendisiyle üretiyor: `[tek] * 5` hiçbir şey var etmiyor — **0** — ve beş yuvanın
beşi de aynı nesneye gidiyor. Çarpma yuva çoğaltır, nesne çoğaltmaz.

Son iki satır kimlik sınamalarını veriyor. `carpim[0] is carpim[4]` **True**: çarpımın
ürettiği yuvalar aynı nesneyi paylaşıyor. `liste[0] is liste[1]` ise **False**: bin öğelik
listede yuvaların hepsi ayrı nesneye gidiyor, çünkü her biri ayrı bir `Oge(i)` çağrısından
geldi. İki liste de beş ya da bin uzunluktadır; farkı uzunluk değil, yuvaların **nereye**
baktığı belirler.

## Büyütmenin Biçimleri

Listeyi büyütmenin birden çok yazımı vardır ve hepsi aynı uzunluğu vermez, aynı kabı
vermez. Python Temelleri kursunda `n + m` ile `n += m` ayrımı **hangi yöntemi çağırdıklarıyla**
ölçülmüştü: ilki `__add__`, ikincisi `__iadd__`. Burada ölçülen şey aynı ayrımın **kaç kap**
var ettiğidir. İkinci ölçüm sekiz yazımı yan yana koyar ve her birine üç soru sorar: kaç
yeni öğe var edildi, sonuç **aynı kap mı** kaldı, ve yuvaların kaçı **eskiden var olan** bir
nesneye gidiyor.

- **KL6** — Sekiz biçim de aynı beş öğelik havuzun **tazeden kurulmuş** bir listesiyle
  başlar; havuzun öğeleri ölçümden önce var edilir ve sayaç her biçimden önce sıfırlanır.
- **KL7** — "Aynı kap" sütunu, işlemden önce tutulan bağla sonucun `is` karşılaştırmasıdır;
  kap sayısı basılmaz, yalnız aynılık sınanır.
- **KL8** — "Eski nesneye giden yuva" sütunu, sonuçtaki her yuvanın havuzdaki ya da ek
  listedeki bir nesneyle `is` karşılaştırılmasıyla bulunur.
- **KL9** — Sıralama ölçümü bir **anahtar işleviyle** yapılır; öğe sınıfına karşılaştırma
  yöntemi eklenmez, böylece sayma düzeni değişmez. Sıralamanın kaç karşılaştırma yaptığı bu
  derste ölçülmez.

```python
"""Listeyi buyutmenin bicimleri: hangisi yeni kap kurar, hangisi var olani buyutur."""

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, 1, 5)]
EK = [Oge(i) for i in (9, 2, 6)]
ESKILER = HAVUZ + EK


def sona_ekle(a):
    a.append(Oge(0))
    return a


def basa_ekle(a):
    a.insert(0, Oge(0))
    return a


def uzat(a):
    a.extend(EK)
    return a


def toplama(a):
    return a + EK


def yerinde_toplama(a):
    a += EK
    return a


def carpma(a):
    return a * 2


def siralama(a):
    return sorted(a, key=deger)


def yerinde_siralama(a):
    a.sort(key=deger)
    return a


BICIMLER = (("a.append(yeni)", sona_ekle), ("a.insert(0, yeni)", basa_ekle),
            ("a.extend(b)", uzat), ("a = a + b", toplama),
            ("a += b", yerinde_toplama), ("a = a * 2", carpma),
            ("a = sorted(a, ...)", siralama), ("a.sort(...)", yerinde_siralama))

print(f"{'biçim':<20s}{'yeni öğe':>9s}{'aynı kap':>10s}{'yuva':>6s}"
      f"{'eski nesneye giden yuva':>25s}")
for ad, islem in BICIMLER:
    a = list(HAVUZ)
    once = a
    sifirla()
    sonuc = islem(a)
    eski = sum(1 for x in sonuc if any(x is y for y in ESKILER))
    print(f"{ad:<20s}{uretilen():>9d}{str(sonuc is once):>10s}"
          f"{len(sonuc):>6d}{eski:>25d}")
```

```
biçim                yeni öğe  aynı kap  yuva  eski nesneye giden yuva
a.append(yeni)              1      True     6                        5
a.insert(0, yeni)           1      True     6                        5
a.extend(b)                 0      True     8                        8
a = a + b                   0     False     8                        8
a += b                      0      True     8                        8
a = a * 2                   0     False    10                       10
a = sorted(a, ...)          0     False     5                        5
a.sort(...)                 0      True     5                        5
```

## Aynı Uzunluk, Ayrı Bedel

"Yeni öğe" sütunu sekiz satırın altısında **0**. Yalnız `append` ve `insert` birer nesne var
ediyor, o da eklenmek üzere yazılan `Oge(0)` çağrısından. Geri kalan altı biçim tek bir öğe
bile üretmiyor: hepsi var olan nesnelere giden **yeni yuvalar** açıyor ya da mevcut yuvaları
yeniden düzenliyor. Son sütun bunu satır satır doğruluyor — yuvaların tamamı, eklenen taze
öğe dışında, ölçümden önce var edilmiş nesnelere gidiyor.

Asıl ayrım "aynı kap" sütununda. `a.extend(b)` ile `a = a + b` aynı sekiz öğeli sonucu
veriyor, ama biri var olan kabı büyütüyor, öbürü **yeni bir kap** kurup adı ona bağlıyor.
`a += b` ise adına rağmen toplama değil, uzatma yapıyor: sonuç **aynı kaptır**. Python
Temelleri kursunda bu ikisinin ayrı özel yöntem çağırdığı sayılmıştı; buradaki sayı o
çağrının sonucudur. Farkın gözlenebilir olması için listeye başka bir ad bağlı olması yeter:
`a += b` yazıldığında o ad da uzamış listeyi görür, `a = a + b` yazıldığında eski beş öğeli
listede kalır.

`sorted` ile `sort` aynı ikiliği sıralama tarafında tekrarlıyor. İkisi de **0** yeni öğe
üretiyor ve ikisinin de sonucunda **5** yuva var; fark, birinin yeni bir kap döndürüp öbürünün
var olan kabı yerinde yeniden dizmesi. `sort` bir liste döndürmez, `None` döndürür — çünkü
döndürecek yeni bir kap yoktur.

Bir şey bu tablonun **dışındadır** ve tabloya bakarak bulunamaz: `append` ile `insert(0, ...)`
aynı sayıları veriyor, oysa yaptıkları iş aynı değildir. Başa eklemek kendinden sonraki bütün
yuvaları kaydırmayı gerektirir, sona eklemek gerektirmez. Bu fark nesne sayısında görünmez,
çünkü kaydırma nesne var etmez — yalnız yuvaları yeniden yazar. Kaydırmanın büyüme sınıfı
Algoritmalar kursunda kuruldu ve burada tekrarlanmaz; bu dersin ölçtüğü eksende iki biçim
gerçekten eşittir.

## Silmek Neyi Serbest Bırakır

Ekleme tarafı bir kabın nesne var etmediğini gösterdi. Silme tarafı bunun karşılığını
gösterir: bir kap nesne **yok da etmez**. Silme işlemleri yalnız yuvayı kapatır; nesnenin
yaşamaya devam edip etmediğini ona bağlı kalan başka adlar ve başka yuvalar belirler.
Üçüncü ölçüm bir listeyi dört ayrı yazımla boşaltır ve her adımda aynı öğeye bağlı ikinci
bir kaba bakar.

- **KL10** — Ölçüm tek bir liste üzerinde **sırayla** ilerler; her satır bir öncekinin
  bıraktığı durumdan devam eder ve yuva sayıları bu yüzden azalarak gider.
- **KL11** — İkinci kap ölçüm başında kurulur ve ölçüm boyunca **hiç dokunulmaz**; ondaki
  değişiklik yalnız birinci kaptan gelebilirdi.
- **KL12** — Eşitliğe bakan silme, öğe sınıfı eşitlik tanımlamadığı için **kimliğe düşer**;
  bu ders eşitlik tanımlayan bir öğeyle ölçüm yapmaz.

```python
"""Silmek nesneyi yok etmez, bagi koparir. Paylasilan oge oteki kapta durur."""

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"]


sifirla()
a = [Oge(i) for i in range(5)]
elde = a[2]
c = [a[0], a[2]]
kurulum = uretilen()

print(f"{'işlem':<20s}{'var edilen':>11s}{'a yuva':>8s}{'c yuva':>8s}"
      f"{'c[1] is elde':>14s}")
print(f"{'beş öğeyle kurmak':<20s}{kurulum:>11d}{len(a):>8d}{len(c):>8d}"
      f"{str(c[1] is elde):>14s}")


def sondan_al():
    a.pop()


def bastan_sil():
    del a[0]


def esitle_sil():
    a.remove(elde)


def bosalt():
    a.clear()


for ad, islem in (("a.pop()", sondan_al), ("del a[0]", bastan_sil),
                  ("a.remove(elde)", esitle_sil), ("a.clear()", bosalt)):
    sifirla()
    islem()
    print(f"{ad:<20s}{uretilen():>11d}{len(a):>8d}{len(c):>8d}"
          f"{str(c[1] is elde):>14s}")

print()
print(f"a boşaldıktan sonra elde tutulan öğe: {elde} | c: {c}")
```

```
işlem                var edilen  a yuva  c yuva  c[1] is elde
beş öğeyle kurmak             5       5       2          True
a.pop()                       0       4       2          True
del a[0]                      0       3       2          True
a.remove(elde)                0       2       2          True
a.clear()                     0       0       2          True

a boşaldıktan sonra elde tutulan öğe: Oge(2) | c: [Oge(0), Oge(2)]
```

Dört silme yazımı da **0** nesne var ediyor — bu beklenirdi. Söylediği asıl şey sağdaki iki
sütunda. Birinci kabın yuvası beşten sıfıra inerken ikinci kabın yuvası **2**'de sabit
kalıyor ve `c[1] is elde` her satırda **True**. Birinci liste tamamen boşaldıktan sonra bile
paylaşılan öğe okunabiliyor: son satır `Oge(2)` basıyor.

Buradan çıkan kural şudur: **bir kaptan silmek, o kabın o nesneye giden bağını koparır;
nesneyi değil.** Nesne, ona bağlı kalan başka bir ad ya da başka bir yuva olduğu sürece
durur. Bin öğelik bir listeyi boşaltmak, o bin nesnenin serbest kalacağı anlamına gelmez —
öğelerin bir kısmı başka bir kapta duruyorsa orada durmayı sürdürür. Bir kabın "tuttuğu"
nesne bu yüzden ölçülen üç sayıdan biridir: var edilen nesne sayısı işi kimin yaptığını,
tutulan yuva sayısı kabın büyüklüğünü, paylaşım ise silmenin gerçekte neyi serbest
bıraktığını söyler.

Eşitliğe bakan silme bir ayrıntı ekliyor. `remove` bir yuvayı kimliğine göre değil,
**eşitliğine** göre bulur; ölçümdeki öğe sınıfı eşitlik tanımlamadığı için eşitlik burada
kimliğe düşüyor ve iki ölçüt aynı sonucu veriyor. Eşitlik tanımlayan bir öğede ikisi
ayrışırdı: `remove` eşit görünen **ilk** yuvayı silerdi, elde tutulan nesneyi değil.

## Özet

- Liste öğeleri içine almaz; her yuva bir nesneye giden bağdır. Bin öğe koymak **1000** nesne
  var eder, listeyi ikinci bir ada bağlamak **0**.
- Yuva sayısı ile nesne sayısı ayrı sayılardır: aynı öğeyi beş kez eklemek **5** yuva ve
  **1** ayrı nesne verir, `[tek] * 5` ise **0** nesne var edip beş yuvayı aynı nesneye
  bağlar.
- Büyütmenin sekiz biçiminden yalnız `append` ve `insert` yeni öğe var eder; kalan altısı
  yalnız yuva açar ve yuvaların hepsi eskiden var olan nesnelere gider.
- `a = a + b`, `a = a * 2` ve `sorted` yeni bir kap kurar; `extend`, `a += b` ve `sort` var
  olan kabı yerinde değiştirir — aynı uzunluk, ayrı kap.
- Nesne sayısı her farkı göstermez: `append` ile `insert(0, ...)` bu eksende eşittir, çünkü
  yuva kaydırmak nesne var etmez.

## Sonraki Adım

Bu dersin bütün ölçümleri listenin **değiştirilebilir** olmasına dayanıyordu: yuva
eklenebiliyor, silinebiliyor, yeniden dizilebiliyordu. Peki bir kap bunların hiçbirine izin
vermezse ne kazanır? Sonraki ders aynı ölçümleri değişmez bir sıralı kapta yineler ve iki
soruyu sorar: değişmezlik **hangi işlemi** gerçekten imkânsız kılar, ve bu imkânsızlığın
karşılığında kabın kazandığı yetki nedir? Yanıtın bir ucu, listenin yapamadığı bir işte
görünecek — bir kabın başka bir kabın **anahtarı** olması.
