Listeler, demetler ve referans sezgisi

Şimdiye kadar bir değişkende çoğunlukla tek bir değer tuttuk. Gerçek programlarda ise bir öğrencinin sınav puanları, bir ürünün haftalık satışları ya da bir sınıftaki adlar gibi birden fazla değeri birlikte saklamak gerekir.

Bu hafta Python’ın iki temel koleksiyonunu (birden fazla değeri bir arada tutan yapı) öğreneceğiz: liste (list) ve demet (tuple). Ayrıca iki değişken aynı listeyi gösterdiğinde ne olduğuna bakacağız. Bu durum, listenin içeriği sonradan değiştirilebildiği için ortaya çıkar.

Bu sayfadaki kod hücreleri kendiliğinden çalışmaz. Her hücrede önce çıktıyı tahmin edin, sonra Run Code düğmesine basın. Kodu değiştirip yeniden çalıştırabilir, Start Over ile ilk hâline döndürebilirsiniz.

Bu bölümün kapsamı

NoteSınavda sorulur
  • İndeks ve dilimle liste elemanlarına erişim
  • append(), remove() ve in davranışları
  • sort() ile sorted() farkı
  • Liste ile demet ayrımı ve fonksiyondan dönen demeti açma
  • Aynı nesnenin paylaşılması ve bağımsız kopya oluşturma
  • Üzerinde dolaşılan listeyi aynı anda değiştirmenin riski
  • Boş listenin ortalama ve maksimum hesabında uç durum olması
  • Liste kavraması (list comprehension)
  • Tek elemanlı demetin (5,) biçiminde yazılması
  • copy.deepcopy() ile derin kopyalama

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

Puan kâğıdıyla dört işi nasıl yaparsınız?

Bir dersin sınav puanları tek bir kâğıtta, öğrenci numarası sırasıyla alt alta yazılı. 60’ın altında kalan öğrenci bütünlemeye girecek. Bu kâğıtla dört iş yapılacak:

  1. Puanları büyükten küçüğe dizip en yüksek üç puanı ilan etmek. Kâğıttaki numara sırası daha sonra yine lazım.

  2. 60’ın altındaki puanları kâğıttan silip bütünleme listesine yazmak.

  3. Bir asistan kâğıttaki puanlar üzerinde deneme hesapları yapacak, bazı puanların üstünü çizip yenisini yazacak. Asıl puanlar bozulmamalı.

  4. Sınıf ortalamasını ve en yüksek puanı birlikte duyurmak.

  5. bölümde bir işin adımlarını sözde kodla yazmıştık. Bu dört işin adımlarını da öyle, Türkçe ve madde madde yazın. Sonra adımlarınızı şu durumlarla deneyin:

  • Kâğıdı sıraya dizerken üstüne mi yazıyorsunuz? Numara sırası ne oluyor?
  • Kâğıt bir telefon uygulamasındaki liste olsun: bir satırı silince alttaki satırlar bir yukarı kayıyor. Puanlar sırasıyla 45, 40, 70. Adımlarınız “satıra bak, 60’ın altındaysa sil, sıradaki satıra geç” diyorsa 40’a ne olur?
  • Asistana kâğıdın kendisini verdiniz. Asistan bir puanın üstünü çizdi. Sizin elinizdeki puanlar hangisi?
  • Sınava kimse girmedi, kâğıt boş. Ortalama adımınız ne yapıyor?

Python bilmeniz gerekmiyor: “Asistana fotokopi veririm” de bir adım. Adımlarınızı bir kenara yazın. Bölümde her birinin Python’da nasıl yazıldığını göreceğiz. Alıştırmalardan önce listenize döneceğiz.

Liste oluşturmak

Bir liste köşeli parantezlerle oluşturulur:

puanlar = [70, 85, 92, 60]

Liste değerleri belirli bir sırayla tutar. Listedeki her değere eleman, elemanın sıradaki konumuna indeks denir:

Değer:   70   85   92   60
İndeks:   0    1    2    3

String’lerde olduğu gibi indeksler 0’dan başlar. Negatif indeks sondan sayar: -1 son elemandır. Üç satır ne yazar?

Liste dilimleme

  1. bölümde string’lerde kullandığımız dilimleme söz dizimi listelerde de çalışır. Başlangıç dâhil, bitiş hariçtir. Üç satır ne yazar?

puanlar[1:4] indeks 1, 2 ve 3’teki elemanları alır: [85, 92, 60]. puanlar[:3] baştan başlar, indeks 3’e gelmeden durur: [70, 85, 92]. puanlar[-2:] sondan ikinci elemandan sona kadar gider: [60, 78].

String dilimlemeden bir farkı var: sonuç string değil, yeni bir liste olur.

Liste elemanını değiştirmek

  1. bölümde string’lerin değiştirilemez olduğunu gördük: bir string’in tek bir harfini yerinde değiştiremezsiniz. Listeler ise değiştirilebilir (mutable): bir elemanını yerinde değiştirebilirsiniz. Hücre ne yazar?

Burada yeni bir liste oluşturulmadı. Var olan listenin ilk elemanı değişti.

Important

Liste indeksi de listenin sınırları içinde kalmalıdır. Üç elemanlı bir listede geçerli pozitif indeksler 0, 1 ve 2’dir. puanlar[3] yazarsanız Python IndexError verir.

append(), remove() ve in

Listenin sonuna yeni eleman eklemek için append() kullanılır. Belirli bir değeri listeden kaldırmak için remove() kullanılır. İki print() ne yazar?

remove() ilk eşleşen değeri siler. Değer listede yoksa Python ValueError verir. Bu yüzden silmeden önce değerin listede olup olmadığına bakabilirsiniz:

if "kalem" in urunler:
    urunler.remove("kalem")

in, bir değerin listede olup olmadığını denetler ve True ya da False verir. İki satır ne yazar?

Note

append() ve remove() yeni bir liste döndürmez, var olan listeyi değiştirir ve None döndürür. Bu yüzden liste = liste.append(x) yazmayın: liste değişir ama liste adı artık None değerini gösterir.

append ve remove işlemlerinin bir Python listesini nasıl değiştirdiği.

Listeye ekleme ve listeden silme

Tahmin et: liste nasıl değişir?

Aşağıdaki kodu çalıştırmadan önce her print() satırının çıktısını tahmin edin:

Sonra çalıştırıp tahmininizi karşılaştırın.

Alıştırma: eksik puanı ekleyin

Bir öğrencinin üç sınav puanı listede tutuluyor. Dördüncü puan olan 88 değerini listeye ekleyin.

Beklenen sonuç:

[72, 80, 91, 88]

puanlar.append(88) yazabilirsiniz.

puanlar = [72, 80, 91]
puanlar.append(88)

print(puanlar)

Liste üzerinde for ile gezinmek

Bir listedeki her elemanı sırayla işleyebiliriz. Döngünün her turunda puan, listenin sıradaki değerini alır. İkinci hücre ne yazar?

Listede gezinmek için çoğu zaman range() gerekmez. Yalnızca elemanlar lazımsa for ile doğrudan listede dolaşmak daha okunur.

Dolaştığınız listeden aynı döngüde eleman silmeyin

Aşağıdaki kod 60’ın altındaki puanları listeden silmeye çalışıyor. Döngü bitince listede ne kalır?

Çıktı [40, 70] olur, 40 silinmeden kalır. İlk turda döngü indeks 0’daki 45’e bakar ve onu siler. 40 ile 70 birer konum öne kayar: 40 artık indeks 0’da. İkinci turda döngü indeks 1’e, yani 70’e geçer. 40’a hiç bakılmaz.

Warning

Döngü sürerken listenin uzunluğu ve elemanların konumu değişir, bu yüzden bazı elemanlar hiç işlenmeden atlanabilir. Python bu durumda hata vermez. Daha güvenli yol, tutmak istediğiniz değerleri yeni bir listeye eklemektir. Bunu birazdan “Listeye koşullu eleman eklemek” başlığında göreceğiz.

Ortalama hesaplamak

Bir listenin ortalaması için önce toplamı, sonra eleman sayısını kullanabiliriz. Hücre ne yazar? Sonra puanlar = [] yapıp yeniden çalıştırın.

Python’da toplamı veren sum() gibi hazır fonksiyonlar da var. Yine de bu aşamada toplamı döngüyle hesaplıyoruz, çünkü böylece biriktiricinin (her turda güncellenen sonucu tutan değişken) nasıl çalıştığını görürsünüz.

Warning

Boş listenin eleman sayısı 0’dır. toplam / len(puanlar) ifadesi boş listede ZeroDivisionError (sıfıra bölme hatası) verir. Boş liste burada bir uç durumdur (edge case): sıradan girdilerden farklı davranan, kolay gözden kaçan sınırdaki girdi.

Minimum ve maksimum

Python listelerinde en küçük ve en büyük değeri doğrudan bulmak için min() ve max() kullanılabilir. İki satır ne yazar?

Yine de en büyük değeri döngüyle bulmayı (maksimum arama kalıbı) bilmeniz gerekir. İleride “puanı en yüksek öğrencinin adı” gibi sorularda sayının yanında o puanın kime ait olduğunu da bulmamız gerekecek.

Boş olmayan bir liste için ilk elemanı başlangıç kabul edebiliriz:

Adım adım:

  1. İlk değeri “şimdiye kadarki en yüksek” kabul et.
  2. Kalan her değeri bununla karşılaştır.
  3. Daha yüksek değer bulursan en_yuksek değerini güncelle.
Important

Bu kalıp listenin boş olmadığını varsayar. Boş listede puanlar[0] IndexError, max(puanlar) ValueError verir. Fonksiyonu yazarken “liste boş gelirse ne döndürecek?” sorusunu da cevaplamalı ve bunu fonksiyonun sözleşmesine (7. bölüm) yazmalısınız. 11. bölümde kayıtlarla çalışırken boş liste için None döndüreceğiz.

Sıralama: sort() ve sorted()

Bir listeyi küçükten büyüğe sıralamanın iki yolu vardır. sort() var olan listeyi değiştirir. sorted() ise asıl listeye dokunmaz, yeni bir sıralı liste döndürür. İki hücrede puanlar neyi gösterir?

sort() sonuç olarak bir liste döndürmez, None döndürür. yeni = puanlar.sort() yazarsanız liste sıralanır ama yeni None olur.

Ters sıralama için reverse=True yazılır:

print(sorted(puanlar, reverse=True))

Sıralama algoritmalarını bu derste kendimiz yazmayacağız, onları Veri Yapıları ve Programlama dersinde ayrıntılı göreceğiz. Burada var olan listeyi sıralamakla yeni bir sıralı liste almak arasındaki farkı bilmeniz yeterli.

Alıştırma: geçen puanları sayın

Aşağıdaki listede 60 ve üzeri kaç puan olduğunu bulun.

Beklenen sonuç 3’tür.

if puan >= 60: koşulu içinde sayacı bir artırın.

puanlar = [45, 60, 72, 38, 90, 59]
gecen_sayisi = 0

for puan in puanlar:
    if puan >= 60:
        gecen_sayisi = gecen_sayisi + 1

print(gecen_sayisi)

Listeye koşullu eleman eklemek

Bir listedeki bazı değerlerden yeni bir liste oluşturabiliriz. Aşağıdaki kod asıl listeye dokunmadan puanları iki yeni listeye ayırıyor. İki satır ne yazar?

Buna filtreleme denir: yalnızca koşulu sağlayan elemanlar yeni listeye eklenir. Döngü asıl listeyi değiştirmediği için hiçbir eleman atlanmaz.

Demet (tuple)

Demet de liste gibi değerleri belirli bir sırayla tutar, ama oluşturulduktan sonra elemanları değiştirilemez. Demet köşeli parantezle değil, normal parantezle yazılır. İki satır ne yazar?

Bir demetin elemanına yeniden değer atamaya çalışırsak ne olur?

Python TypeError: 'tuple' object does not support item assignment hatası verir. Demetin elemanı okunabilir ama değiştirilemez.

Bu yüzden seçim şöyle yapılır:

  • Liste: içerik zamanla değişecekse.
  • Demet: birkaç değer birlikte küçük ve sabit bir grup oluşturuyorsa.

Örneğin bir rengin RGB bileşenleri (kırmızı, yeşil, mavi) ya da bir konumun enlem ve boylamı demette tutulabilir.

Tek elemanlı demet tuzağı (sınav dışı)

Parantez tek başına demet oluşturmaz. İki satır hangi türü yazar?

Tek elemanlı demeti sondaki virgül belirler. (5) yalnızca 5 değerini paranteze alır, (5,) ise bir elemanlı demettir.

Demet açma ve fonksiyondan birden fazla değer döndürme

Demetteki değerleri ayrı değişkenlere alabiliriz. Buna demet açma (tuple unpacking) denir. Hücre ne yazar?

return satırında değerleri virgülle ayırırsak Python bunları tek bir demette toplar. Hücredeki dört print() ne yazar?

Şu iki return aynı demeti döndürür:

return 0, 100
return (0, 100)

Çağıran tarafta, son iki satırdaki gibi, demeti doğrudan ayrı adlara açabiliriz.

Aynı listeye referans verme

Python’da her liste bellekte bir nesnedir (Python’ın bellekte tuttuğu bir değer). Değişken adı bu nesneyi gösterir. Listeler değiştirilebilir olduğu için şu davranışa dikkat etmek gerekir. İki satır ne yazar?

İki satır da [10, 20, 30, 40] yazar. liste1’e hiç dokunmadık ama o da değişti.

liste2 = liste1 ataması ikinci bir liste oluşturmaz. İki değişken bellekteki aynı liste nesnesini gösterir. Bu duruma aynı nesneye referans verme (aliasing) denir. Asistana puan kâğıdının fotokopisini değil, kâğıdın kendisini vermek gibidir.

Bunu şöyle düşünebilirsiniz:

liste1 ─┐
        ├──> [10, 20, 30, 40]
liste2 ─┘

liste2 ile yaptığınız değişiklik bu tek listeyi değiştirir. Bu yüzden liste1’i yazdırdığınızda da aynı değişikliği görürsünüz.

Tahmin et: iki değişken mi, iki liste mi?

Çalıştırmadan önce çıktıyı tahmin edin:

Sonucu görünce “Python a’yı gizlice değiştirdi” diye düşünmeyin. Ortada tek bir liste var ve iki ad da onu gösteriyor.

Bağımsız kopya oluşturmak

Bağımsız bir liste gerekiyorsa .copy() kullanabiliriz. Bu kez iki satır ne yazar?

İlk satır [1, 2, 3], ikinci satır [1, 2, 3, 4] yazar. .copy() yeni bir liste nesnesi oluşturdu. 4 yalnız kopyaya eklendi.

Tam dilim ([:], başı ve sonu boş bırakılmış dilim) de listenin kopyasını verir: kopya = orijinal[:]. Bu derste çoğunlukla .copy() kullanacağız, çünkü kopya istediğimizi daha açık gösterir. Başka kaynaklarda liste[:] görürseniz onun da aynı işi yaptığını bilin.

İkisi de sığ kopya (shallow copy) oluşturur: liste yenidir ama içindeki elemanlar kopyalanmaz, iki liste aynı elemanları gösterir. İçinde başka liste olmayan (tek seviyeli) bir listede bu ayrıntı sorun çıkarmaz. İç içe listelerin kopyalanmasına bu derste girmiyoruz.

b = a ile aynı listeye referans verme ve a.copy() ile bağımsız liste oluşturma farkı.

Aynı listeyi paylaşma ve kopyalama

Alıştırma: bağımsız çalışma listesi

Aşağıdaki kodda taslak listesine yapılan değişiklik orijinal listeyi de değiştiriyor. taslak için bağımsız bir kopya oluşturun.

Beklenen:

Orijinal: ['A', 'B', 'C']
Taslak: ['A', 'B', 'C', 'D']

taslak = orijinal.copy() yazın.

orijinal = ["A", "B", "C"]
taslak = orijinal.copy()

taslak.append("D")

print("Orijinal:", orijinal)
print("Taslak:", taslak)

Fonksiyona liste vermek

Bir fonksiyona argüman olarak liste de verebiliriz. Hücre ne yazar?

Fonksiyon listeyi yalnızca okuyorsa ne yaptığını izlemek kolaydır. Listeyi değiştiren bir fonksiyon ise çağıran koddaki listeyi de değiştirir, çünkü fonksiyon listenin kopyasıyla değil kendisiyle çalışır. Aşağıdaki hücrede notlar değişir mi?

[0, 85] yazar. Fonksiyon çağrılınca puanlar parametresi notlar ile aynı listeyi gösterir, b = a atamasındaki gibi. Fonksiyonun içindeki değişiklik o tek listeyi değiştirir.

Tip

Bir fonksiyonu kullanan kişi, ona verdiği listenin değişip değişmeyeceğini bilmelidir. Hesap yapan fonksiyonlarda listeyi yalnızca okuyun. Yeni bir sonuç gerekiyorsa onu döndürün.

Soruya dönelim: puan kâğıdı Python’da

Bölümün başında puan kâğıdıyla yapılacak dört işin adımlarını yazıp birkaç durumla denemiştiniz. Python’daki karşılıkları şöyle:

İş Sözde kodda Python’da Dikkat
En yüksek üç puanı ilan etmek, numara sırasını korumak “Puanları büyükten küçüğe başka bir kâğıda diz, ilk üçünü oku” sirali = sorted(puanlar, reverse=True), sonra sirali[:3] puanlar.sort() asıl listeyi sıralar, numara sırası kaybolur. sort() yeni liste döndürmez, None döndürür
60’ın altındakileri bütünleme listesine almak “Her satıra bak, 60’ın altındaysa bütünleme listesine yaz” Yeni listeler: butunleme.append(puan), gecenler.append(puan) Dolaşılan listeden remove() ile silmek kayan elemanı atlar: 45, 40, 70’te 40 kalır
Asistanın asıl puanları bozmaması “Asistana fotokopi ver” taslak = puanlar.copy() taslak = puanlar kâğıdın kendisini vermektir: asistanın değişikliği asıl listede de görünür
Ortalama ve en yüksek puanı birlikte duyurmak “Kâğıt boşsa duyuru yapma. Değilse ortalamayı ve en yüksek puanı bul” if len(puanlar) == 0: kontrolü, sonra return ortalama, en_yuksek ve ort, eb = ozet(puanlar) Boş listede bölme ZeroDivisionError, max() ValueError verir. İki değer tek bir demet olarak döner

Listenizi tabloyla karşılaştırın. “Satıra bak, sil, sıradaki satıra geç” yazdıysanız kâğıtta doğru çalışan adım, kayan listede bir elemanı atlar. “Asistana kâğıdı veririm” yazdıysanız Python’daki = de bunu yapar: kopya almaz, aynı listeye ikinci bir ad verir. Boş kâğıdı düşünmediyseniz program da düşünmez: bölme hatası verir.

Üret: puan özetini hesaplayın

Bölümün başındaki dördüncü işi bir fonksiyonla yapın. puan_ozeti(puanlar) adlı fonksiyon:

  • Toplamı döngüyle hesaplamalı,
  • Ortalamayı bulmalı,
  • 60 ve üzeri puanların sayısını hesaplamalı,
  • Sonucu (ortalama, gecen_sayisi) biçiminde bir demet olarak döndürmeli,
  • Liste boşsa bölme yapmadan (None, 0) döndürmeli.

Başlangıç:

Beklenen sonuç:

(58.4, 2)
(None, 0)

Önce if len(puanlar) == 0: ile boş listeyi ayırın. Sonra toplam ve 60 üzeri sayaç için iki ayrı biriktirici kullanın. Ortalama toplam / len(puanlar) olur.

def puan_ozeti(puanlar):
    if len(puanlar) == 0:
        return None, 0

    toplam = 0
    gecen_sayisi = 0

    for puan in puanlar:
        toplam = toplam + puan
        if puan >= 60:
            gecen_sayisi = gecen_sayisi + 1

    ortalama = toplam / len(puanlar)
    return ortalama, gecen_sayisi

print(puan_ozeti([45, 40, 70, 82, 55]))
print(puan_ozeti([]))

Dikkat edin: return ortalama, gecen_sayisi satırı (ortalama, gecen_sayisi) demetini döndürür. Çağıran taraf ortalama, gecen = puan_ozeti(puanlar) yazarak iki değeri doğrudan ayrı değişkenlere alabilir.

Sınav provası

Önce kendi cevabınızı seçin, sonra cevap anahtarında her şıkkın neden doğru ya da yanlış olduğunu okuyun. Yanlış şıklar rastgele yazılmadı; bu konuda öğrencilerin gerçekten yaptığı hatalardan seçildi. Sınav soruları da aynı yolla hazırlanır.

Madde 1. [10, 20, 30, 40][1:3] ifadesinin sonucu nedir?

  • A. 20 ve 30 ayrı ayrı
  • B. [20, 30, 40]
  • C. [10, 20, 30]
  • D. [20, 30]
  • E. [10, 20]

Madde 2. append() ve remove() sırasıyla ne yapar?

  • A. append() başa ekler; remove() son elemanı siler
  • B. append() sona ekler, remove() verilen değeri siler
  • C. append() listeyi sıralar; remove() listeyi boşaltır
  • D. İkisi de yeni bir liste döndürür
  • E. append() eleman ekler; remove() verilen indeksteki elemanı siler

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

sayilar = [3, 1, 2]
yeni = sayilar.sort()
print(yeni)
  • A. None
  • B. Hata verir; sort() bir değişkene atanamaz
  • C. [1, 2, 3]
  • D. Boş liste
  • E. [3, 1, 2]

Madde 4. sort() ile sorted() arasındaki temel fark nedir?

  • A. İkisi aynıdır; sorted() yalnızca daha yeni yazımdır
  • B. sort() artan, sorted() azalan sırada sıralar
  • C. sort() yerinde sıralar, sorted() yeni liste döndürür
  • D. sort() sayılarda, sorted() metinlerde çalışır
  • E. sorted() listeyi yerinde değiştirir, sort() kopyalar

Madde 5. Liste ile demet arasındaki temel fark nedir?

  • A. Demet indekslenemez, yalnızca döngüyle okunur
  • B. Liste yalnızca sayı, demet yalnızca metin tutar
  • C. Liste değiştirilebilir, demet değiştirilemez
  • D. Liste sıralı, demet sırasızdır
  • E. Liste bellekte, demet diskte tutulur

Madde 6. Aşağıdaki fonksiyon ne tür bir değer döndürür ve çağıran tarafta nasıl açılır?

def en_kucuk_en_buyuk(sayilar):
    return min(sayilar), max(sayilar)
  • A. Demet döndürür; a, b = en_kucuk_en_buyuk(liste) ile açılır
  • B. Yalnızca min(sayilar) döner; ikinci değer yok sayılır
  • C. Bir liste döndürür; append() ile genişletilebilir
  • D. İki ayrı değer döndürür; her biri için ayrı bir çağrı gerekir
  • E. Hata verir; return tek bir değer alabilir

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

a = [1, 2, 3]
b = a
b.append(4)
print(a)
  • A. [4]
  • B. [1, 2, 3]
  • C. None
  • D. [1, 2, 3, 4]
  • E. Hata verir; bir liste iki değişkene atanamaz

Madde 8. Tek seviyeli bir listenin bağımsız kopyasını oluşturmak için hangisi kullanılır?

  • A. b = a.append()
  • B. b = a
  • C. b = sorted(a) her zaman doğru kopyalama yöntemidir
  • D. b = list
  • E. b = a.copy() veya b = a[:]

Madde 9. Üzerinde for ile dolaşılan bir listeden aynı anda remove() yapmak neden risklidir?

  • A. Riskli değildir; remove() döngüyle uyumludur
  • B. Döngü hiç bitmez, sonsuza kadar döner
  • C. Python bu işlemi engeller ve hata verir
  • D. Liste döngü sırasında kendiliğinden demete dönüşür
  • E. Silinen elemandan sonrakiler atlanabilir

Madde 10. Boş liste ortalama hesabında neden özel bir durumdur?

  • A. Boş listede len() çalışmaz
  • B. Eleman sayısı sıfırdır, bölme işlemi hata verir
  • C. Boş listenin ortalaması kendiliğinden 0 olur
  • D. Boş liste Python’da None ile aynıdır
  • E. Özel bir durum değildir; ortalama her listede hesaplanabilir

Madde 1. Doğru: D. Dilimlemede başlangıç dâhil, bitiş hariçtir; 3 numaralı eleman alınmaz.

  • A yanlış: Seçilen değerler doğru bulunmuş, ama dilimin onları tek tek verdiği sanılmış. Dilimin sonucu her zaman tek bir listedir: [20, 30].
  • B yanlış: 1:3 “birden üçe kadar” diye okununca 3 numaralı eleman da dâhil sanılır. Ama bitiş indeksi dilime girmez; indeks 3’teki 40 alınmaz.
  • C yanlış: Günlük sayımda ilk eleman “birinci” olduğu için indeksler 1’den sayılır ve dilim baştan başlıyormuş gibi görünür. Ama indeksler 0’dan başlar; 1 ikinci elemanı, yani 20’yi gösterir.
  • E yanlış: 1:3 iki eleman aldığı için baştaki iki eleman seçilir sanılabilir. Eleman sayısı doğru ama dilim 0’dan değil 1’den başlar.

Madde 2. Doğru: B. append() elemanı listenin sonuna ekler. remove() indekse değil değere göre çalışır ve yalnızca ilk eşleşmeyi kaldırır.

  • A yanlış: Ekleme ile silmenin listenin iki ayrı ucunda yapıldığı düşünülünce simetrik görünür. Ama append() sona ekler; son elemanı silmek pop() işidir.
  • C yanlış: İki metot da listeyi değiştirdiği için listeyi değiştiren öteki metotlarla karışabilir. Ama sıralama sort(), boşaltma clear() işidir.
  • D yanlış: String metotları yeni değer döndürdüğü için liste metotlarının da öyle yaptığı sanılır. Ama ikisi de listeyi yerinde değiştirir ve None döndürür.
  • E yanlış: Listelerde çoğu işlem indeksle yapıldığı için remove()un da indeks aldığı sanılır. Ama remove() indeks değil değer alır; indeksle silmek için del ya da pop() kullanılır.

Madde 3. Doğru: A. sort() listeyi yerinde sıralar ve None döndürür. Sıralı liste isteniyorsa sorted() kullanılır.

  • B yanlış: sort()un sonucunu kullanmanın yanlış olduğunu bilen öğrenci bunun yasak olduğunu düşünebilir. Ama atama hata vermez; atanan değer None olur.
  • C yanlış: Liste gerçekten sıralandığı için yeni değişkeninin de sıralı listeyi tuttuğu sanılır. Ama bu sorted(sayilar) sonucudur; sort() listeyi yerinde sıralar ve yeni liste döndürmez.
  • D yanlış: Dönüş değeri “hiçbir şey” olunca bunun boş bir liste olduğu sanılabilir. Ama None ile [] farklı değerlerdir; liste de boşalmaz, yerinde sıralanır.
  • E yanlış: yeni adı listenin sıralanmadan önceki bir kopyasını tutuyormuş gibi düşünülebilir. Ama yeni listeyi değil, sort()un dönüş değeri olan None’ı tutar.

Madde 4. Doğru: C. sort() listeyi yerinde sıralar ve None döndürür. sorted() özgün listeyi bozmadan yeni bir sıralı liste döndürür. Özgün sıranın korunması gerekiyorsa sorted(), gerekmiyorsa sort() seçilir.

  • A yanlış: İkisi de sonunda sıralı bir liste gösterdiği için aynı sanılır. Ama davranışları farklıdır; biri yerinde çalışır, öteki yeni bir liste döndürür.
  • B yanlış: İki ayrı ad görünce iki ayrı yön bekleyen öğrenci bunu seçer. Ama ikisi de varsayılan olarak artan sıralar; yön reverse ile değiştirilir.
  • D yanlış: İki ayrı fonksiyonun ayrı türler için yazıldığı sanılabilir. Ama ikisi de her iki türle çalışır.
  • E yanlış: İkisinin farklı çalıştığını bilen ama hangisinin ne yaptığını karıştıran öğrenci bunu seçer. Görevler ters yazılmış; sorted() özgün listeye dokunmaz.

Madde 5. Doğru: C. Listeye oluşturulduktan sonra eleman eklenip çıkarılabilir; demet oluşturulduktan sonra değiştirilemez. Demet seçmek, bu değerlerin program boyunca değişmeyeceğini de gösterir.

  • A yanlış: Demetin değiştirilemediğini bilen öğrenci ona köşeli parantezle erişilemeyeceğini de düşünebilir. Ama demet indekslenebilir; yalnızca elemanı değiştirilemez.
  • B yanlış: Farklı yapıların farklı türler için olduğu düşünülebilir. Ama ikisi de her türü tutabilir.
  • D yanlış: Sırasız bir koleksiyon olan kümeyle karıştırıldığı için akla gelir. Ama ikisi de sıralıdır; sırasız olan kümedir.
  • E yanlış: Değişmeyen verinin kalıcı bir yerde saklandığı düşünülebilir. Ama ikisi de bellekte tutulur.

Madde 6. Doğru: A. Virgülle ayrılmış birden fazla değer tek bir demet olarak döner. Çağıran tarafta kucuk, buyuk = en_kucuk_en_buyuk(liste) gibi bir satırla ayrı adlara açılabilir.

  • B yanlış: returnun fonksiyonu hemen bitirdiğini bilen öğrenci ilk değerden sonrasının kaybolduğunu düşünebilir. Ama ikisi de döner; return virgülle birden fazla değer taşıyabilir.
  • C yanlış: Birden fazla değeri bir arada tutan yapı denince akla önce liste gelir. Ama köşeli parantez yazılmadığı için sonuç demettir ve demete append() uygulanamaz.
  • D yanlış: return satırında iki ayrı fonksiyon çağrısı göründüğü için iki ayrı sonuç beklenir. Ama tek çağrı yeter; dönen tek değer, iki eleman taşıyan bir demettir.
  • E yanlış: Önceki örneklerde return hep tek değer döndürdüğü için bu bir kural sanılabilir. Ama virgülle ayrılan değerler tek bir demet oluşturur; bu geçerlidir.

Madde 7. Doğru: D. b = a kopya oluşturmaz; iki ad aynı listeyi gösterir. b ile yapılan ekleme ada da görünür.

  • A yanlış: append() bir değer “koyduğu” için listeyi o değerle değiştiriyormuş gibi düşünülebilir. Ama append() var olan elemanları silmez, yeni değeri sona ekler.
  • B yanlış: a koddan sonra hiç değiştirilmediği için ilk değerinde kalır sanılır. Ama b = a kopya oluşturmaz; b üzerinden yapılan ekleme aynı listeyi değiştirir ve ada da görünür.
  • C yanlış: append() None döndürdüğü için yazdırılan değerin de None olduğu sanılabilir. Ama print(a) append()un sonucunu değil, a listesinin kendisini yazar.
  • E yanlış: Bir değerin tek bir adı olur diye düşünen öğrenci ikinci atamayı hatalı sanar. Ama aynı nesneye istenildiği kadar ad bağlanabilir.

Madde 8. Doğru: E. İkisi de yeni bir liste nesnesi oluşturur; tek seviyeli listelerde bağımsız kopya sağlar.

  • A yanlış: append() listeye bir şey eklediği için yeni bir liste verdiği sanılabilir. Ama append() var olan listeyi değiştirir ve None döndürür; ayrıca eklenecek değeri argüman olarak ister.
  • B yanlış: Sayılarda b = a ayrı bir değer veriyormuş gibi göründüğü için listede de kopya aldığı sanılır. Ama bu yalnızca ikinci bir ad oluşturur; iki ad aynı listeyi gösterir.
  • C yanlış: sorted() asıl listeye dokunmadan yeni bir liste döndürdüğü için kopya yerine geçebilir gibi görünür. Ama elemanların sırasını da değiştirir; sırası bozulmamış bir kopya vermez.
  • D yanlış: list adı “liste oluştur” gibi okunduğu için yeni bir liste vereceği düşünülebilir. Ama parantezsiz list türün kendisidir; bu satır bye türü bağlar, kopya oluşturmaz.

Madde 9. Doğru: E. Eleman silinince sonraki elemanlar öne kayar ama döngü bir sonraki konumdan devam eder; kayan eleman işlenmeden atlanır. Bu yüzden ya yeni bir liste kurulur ya da listenin bir kopyası üzerinde dolaşılır.

  • A yanlış: Küçük örneklerde sonuç çoğu zaman doğru çıktığı için sorun fark edilmeyebilir. Ama art arda silinmesi gereken elemanlardan biri atlanır ve bu gözden kaçan bir hataya yol açar.
  • B yanlış: Döngü sırasında liste değiştiği için döngünün sonunu bulamayacağı sanılabilir. Ama döngü sonlanır; sorun bazı elemanların hiç işlenmemesi.
  • C yanlış: Riskli bir işlemin Python tarafından engelleneceği beklenir. Ama çoğu zaman hata vermez, yanlış sonuçla devam eder; tehlikeli olan da budur.
  • D yanlış: Döngü sırasında listenin korunması gerektiği fikri demetin değiştirilemezliğini akla getirir. Ama tür değişmez; liste liste olarak kalır.

Madde 10. Doğru: B. Ortalama, toplamın eleman sayısına bölünmesidir. Boş listede eleman sayısı sıfır olduğu için ZeroDivisionError çıkar. Bu yüzden boş veri durumu ayrıca denetlenir: fonksiyon ya None döndürür ya da açık bir hata bildirir.

  • A yanlış: Sayılacak eleman olmadığı için len()in çalışmayacağı sanılabilir. Ama len([]) sonucu 0’dır ve sorunsuz çalışır; sorun o 0’a bölmektir.
  • C yanlış: Toplamı 0 olan bir listenin ortalamasının da 0 olacağı düşünülebilir. Ama Python kendiliğinden 0 vermez; bölme hata verir.
  • D yanlış: İkisi de “veri yok” gibi düşünüldüğü için karıştırılır. Ama [] bir listedir; None ayrı bir değerdir.
  • E yanlış: Ortalama formülü her listede aynı olduğu için her zaman çalışacağı düşünülebilir. Ama boş listede hesaplanamaz; bölen sıfır olur.

Tek sayfa özet

Bu hafta birden fazla değeri birlikte tutmaya başladık.

  • Liste sıralı ve değiştirilebilir bir koleksiyondur.
  • String dilimleme söz dizimi listelerde de çalışır. Dilimin sonucu yeni bir listedir.
  • Liste elemanlarına indeksle erişilebilir ve elemanlar değiştirilebilir. Sınırın dışındaki indeks IndexError verir.
  • append() listenin sonuna eleman ekler, remove() ilk eşleşen değeri siler, in değerin listede olup olmadığını söyler. append() ve remove() None döndürür.
  • Üzerinde dolaşılan listeyi aynı anda remove() ile değiştirmek eleman atlatır: [45, 40, 70] listesinden 60 altını silerken 40 kalır. Tutulacak değerleri yeni bir listeye eklemek güvenlidir.
  • min() ve max() en küçük ve en büyük değeri doğrudan verir. Döngüyle yazılan “şimdiye kadarki en büyük” kalıbı ise değerin yanında kime ait olduğunu da bulmak gerektiğinde işe yarar.
  • sort() listeyi yerinde değiştirir ve None döndürür. sorted() asıl listeye dokunmaz, yeni sıralı liste döndürür.
  • for ile liste elemanlarında doğrudan dolaşılabilir.
  • Koşulu sağlayan elemanları yeni bir listeye eklemek filtreleme kalıbıdır.
  • Demet sıralıdır ancak değiştirilemez.
  • Fonksiyonda return a, b iki değeri bir demet olarak döndürür ve çağıran tarafta x, y = ... ile açılabilir.
  • b = a ataması bağımsız kopya oluşturmaz, iki değişken aynı listeyi gösterir (aliasing). Bu, kâğıdın fotokopisini değil kendisini vermek gibidir.
  • .copy() ya da tam dilim, tek seviyeli listelerde bağımsız bir sığ kopya oluşturur.
  • Fonksiyona verilen liste kopyalanmaz. Fonksiyon listeyi değiştirirse çağıran koddaki liste de değişir.
  • Boş liste ortalama ve maksimum hesabında bir uç durumdur: bölme ve max() hata verir. Fonksiyon bu durumda ne döndüreceğini açıkça söylemelidir.

Bir sonraki bölümde verilere indeks yerine anlamlı anahtarlarla erişmek için sözlükleri, tekrarsız değerler için ise kümeleri kullanacağız.

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

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

  • İndeks ve dilimle liste elemanlarına erişir.
  • append(), remove() ve in ile listeyi günceller ve sorgular.
  • sort() ile sorted() arasındaki farkı açıklar.
  • Liste ile demeti ayırt eder ve fonksiyondan dönen demeti açar.
  • b = a ile aynı nesnenin paylaşıldığını tanır ve bağımsız kopya oluşturur.
  • Üzerinde dolaşılan listeyi aynı anda değiştirmenin riskini açıklar.
  • Boş listeyi ortalama ve maksimum hesabında uç durum olarak denetler.
Back to top