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ı veya bir sınıftaki isimler gibi birden fazla değeri birlikte saklamak gerekir.

Bu hafta Python’ın en temel koleksiyonlarından olan liste (list) ve demet (tuple) yapılarını öğreneceğiz. Ayrıca listelerin değiştirilebilir olması nedeniyle iki değişkenin aynı listeyi göstermesi durumunda ortaya çıkan davranışı başlangıç düzeyinde inceleyeceğiz.

Bu hafta neleri yapabilmelisiniz?

Bölümün sonunda:

  • liste oluşturabilmeli ve elemanlarına indeks ile erişebilmeli,
  • listedeki bir elemanı değiştirebilmeli,
  • append() ile yeni eleman ekleyebilmeli,
  • len() ile eleman sayısını bulabilmeli,
  • for ile liste elemanları üzerinde gezinebilmeli,
  • basit toplam, ortalama ve filtreleme işlemleri yapabilmeli,
  • liste ile demet arasındaki temel farkı açıklayabilmeli,
  • değiştirilebilir ve değiştirilemez koleksiyon fikrini ayırt edebilmeli,
  • iki değişkenin aynı liste nesnesini göstermesinin etkisini açıklayabilmeli,
  • bağımsız bir liste kopyası gerektiğinde .copy() kullanabilmelisiniz.

Liste oluşturmak

Bir liste köşeli parantezlerle oluşturulur:

puanlar = [70, 85, 92, 60]

Liste birden fazla değeri sıralı biçimde tutar.

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

String’lerde olduğu gibi indeksler 0’dan başlar.

puanlar = [70, 85, 92, 60]

print(puanlar[0])
print(puanlar[2])
print(puanlar[-1])

Çıktı:

70
92
60

Liste elemanını değiştirmek

String değerlerin değiştirilemez olduğunu geçen hafta gördük. Listeler ise değiştirilebilir (mutable) yapılardır.

puanlar = [70, 85, 92]
puanlar[0] = 75

print(puanlar)

Sonuç:

[75, 85, 92]

Burada yeni bir liste oluşturmak yerine mevcut listenin ilk elemanı değiştirildi.

Important

Liste indeksleri de sınırların içinde olmalıdır. Üç elemanlı bir listede geçerli pozitif indeksler 0, 1, 2 değerleridir.

append() ile eleman eklemek

Listenin sonuna yeni eleman eklemek için append() kullanılır:

urunler = ["defter", "kalem"]
urunler.append("silgi")

print(urunler)

Çıktı:

['defter', 'kalem', 'silgi']

append() mevcut listeyi değiştirir.

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:

puanlar = [70, 85, 92]

for puan in puanlar:
    print(puan)

Burada puan, her yinelemede listenin sıradaki değerini alır.

Bir toplam hesabı:

puanlar = [70, 85, 92]
toplam = 0

for puan in puanlar:
    toplam = toplam + puan

print(toplam)

Liste üzerinde gezinirken çoğu zaman ayrıca range() kullanmaya gerek yoktur. Eğer yalnızca elemanlara ihtiyacımız varsa doğrudan liste üzerinde for daha okunurdur.

Ortalama hesaplamak

Bir listenin ortalaması için önce toplamı, sonra eleman sayısını kullanabiliriz:

puanlar = [70, 85, 92, 73]

toplam = 0
for puan in puanlar:
    toplam = toplam + puan

ortalama = toplam / len(puanlar)
print(ortalama)

Python’da sum() gibi hazır fonksiyonlar vardır; ancak bu aşamada biriktirici mantığını görünür tutmak için toplamı döngüyle hesaplamak öğreticidir.

Warning

Boş listenin eleman sayısı 0dır. toplam / len(puanlar) ifadesi boş listede sıfıra bölme hatası üretir. Bu bir uç durumdur.

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

Aşağıdaki listedeki 60 ve üzeri puanların kaç tane olduğunu bulun.

Beklenen sonuç 3tü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:

sicakliklar = [12, 25, 31, 18, 35]
sicak_gunler = []

for sicaklik in sicakliklar:
    if sicaklik >= 30:
        sicak_gunler.append(sicaklik)

print(sicak_gunler)

Sonuç:

[31, 35]

Bu, temel bir filtreleme kalıbıdır: yalnızca koşulu sağlayan elemanları yeni koleksiyona ekleriz.

Demet (tuple)

Demet, listeye benzeyen sıralı bir koleksiyondur; ancak elemanları sonradan değiştirilemez.

koordinat = (41.2867, 36.33)

print(koordinat[0])
print(koordinat[1])

Bir demetin elemanına yeniden değer atayamayız:

koordinat = (41.2867, 36.33)
# koordinat[0] = 42   # Geçerli değildir.

Bu nedenle:

  • liste: içerik zamanla değişecekse uygundur,
  • demet: küçük ve sabit bir değer grubu olarak düşünülüyorsa uygundur.

Örneğin RGB renk bileşenleri veya bir koordinat çifti demetle anlamlı olabilir.

Değiştirilebilir liste ile değiştirilemez demetin temel davranışlarını karşılaştıran şema.

Demet açma

Demetteki değerleri ayrı değişkenlere alabiliriz:

boyut = (1920, 1080)
genislik, yukseklik = boyut

print(genislik)
print(yukseklik)

Bu yapıya tuple unpacking denir; burada yalnızca iki değeri iki değişkene ayırmak için kullanıyoruz.

Aynı listeye referans verme

Listelerin değiştirilebilir olması önemli bir davranışa yol açar.

liste1 = [10, 20, 30]
liste2 = liste1

liste2.append(40)

print(liste1)
print(liste2)

İki çıktı da:

[10, 20, 30, 40]

olur.

Çünkü liste2 = liste1 ifadesi bağımsız ikinci bir liste oluşturmaz. İki değişken aynı liste nesnesini gösterir. Bu duruma aynı nesneye referans verme (aliasing) denir.

Bunu şöyle düşünebilirsiniz:

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

liste2 üzerinden yapılan değişiklik aynı nesne üzerinde gerçekleştiği için liste1 üzerinden de görülür.

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

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

Bu örneğin amacı “Python gizlice değerleri değiştiriyor” düşüncesini önlemektir. Değişen tek liste nesnesidir; iki ad da onu göstermektedir.

Bağımsız kopya oluşturmak

Bağımsız bir liste gerekiyorsa .copy() kullanabiliriz:

orijinal = [1, 2, 3]
kopya = orijinal.copy()

kopya.append(4)

print(orijinal)
print(kopya)

Çıktı:

[1, 2, 3]
[1, 2, 3, 4]

Bu aşamada iç içe listelerde kopyalama ayrıntılarına girmiyoruz. .copy() kullanımını tek seviyeli listeler için ele alıyoruz.

İki değişkenin aynı liste nesnesini göstermesi ile .copy() kullanılarak bağımsız liste oluşturulması arasındaki fark.

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

Fonksiyona liste argümanı verebiliriz:

def en_az_gecen_sayisi(puanlar):
    adet = 0

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

    return adet
print(en_az_gecen_sayisi([45, 70, 81, 50]))

Sonuç 2dir.

Fonksiyon listeyi yalnızca okuyorsa davranışı daha kolay izlenir. Eğer fonksiyon append() veya indeks atamasıyla listeyi değiştiriyorsa çağıran kodun listesi de etkilenebilir.

Tip

Bir fonksiyonun kendisine verilen listeyi değiştirip değiştirmediği önemli bir tasarım bilgisidir. Başlangıçta hesaplama fonksiyonlarında listeyi yalnızca okumayı, yeni sonuç gerekiyorsa yeni değer döndürmeyi tercih edin.

Üret — ölçüm özetini hesaplayın

Bir sensörün sıcaklık ölçümleri şu listede olsun:

olcumler = [18.5, 21.0, 19.5, 24.0, 22.5]

olcum_ozeti(olcumler) adlı bir fonksiyon yazın. Fonksiyon:

  • toplamı döngüyle hesaplamalı,
  • ortalamayı bulmalı,
  • 20 ve üzeri ölçümlerin sayısını hesaplamalı,
  • sonucu (ortalama, sicak_olcum_sayisi) biçiminde bir demet olarak döndürmeli.

Başlangıç:

Beklenen yaklaşık sonuç:

(21.1, 3)

Toplam ve 20 üzeri sayaç için iki ayrı biriktirici kullanabilirsiniz. Ortalama toplam / len(olcumler) olur.

def olcum_ozeti(olcumler):
    toplam = 0
    sicak_olcum_sayisi = 0

    for olcum in olcumler:
        toplam = toplam + olcum
        if olcum >= 20:
            sicak_olcum_sayisi = sicak_olcum_sayisi + 1

    ortalama = toplam / len(olcumler)
    return ortalama, sicak_olcum_sayisi

sonuc = olcum_ozeti([18.5, 21.0, 19.5, 24.0, 22.5])
print(sonuc)

Bölüm özeti

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

  • Liste sıralı ve değiştirilebilir bir koleksiyondur.
  • Liste elemanlarına indeksle erişilebilir ve elemanlar değiştirilebilir.
  • append() listenin sonuna eleman ekler.
  • for, liste elemanlarını doğrudan işlemek için kullanılabilir.
  • Yeni bir listeye yalnızca koşulu sağlayan elemanları eklemek temel filtreleme kalıbıdır.
  • Demet sıralıdır ancak değiştirilemez.
  • b = a ifadesi listelerde bağımsız kopya üretmez; iki değişken aynı nesneyi gösterebilir.
  • .copy() tek seviyeli listelerde bağımsız bir kopya oluşturmak için kullanılabilir.
  • Fonksiyona verilen değiştirilebilir koleksiyonun değiştirilip değiştirilmediği önemli bir tasarım kararıdır.

Kendinizi kontrol edin

  1. [10, 20, 30][1] sonucu nedir?
  2. append() ne yapar?
  3. Liste ile demet arasındaki temel fark nedir?
  4. Neden string’de metin[0] = "A" geçersizken listede liste[0] = "A" geçerlidir?
  5. b = a sonrasında b.append(5) neden a üzerinden de görülebilir?
  6. .copy() ne zaman kullanılır?
  7. Liste üzerinde yalnızca elemanlara ihtiyaç duyuyorsak neden for eleman in liste çoğu zaman range() kullanımından daha okunurdur?
  8. Boş liste ortalama hesabında neden özel durum olabilir?

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.

Back to top