27listeler demetler 2.fw min

Python Ders 27 | Listeler ve Demetler – 2

Liste Üreteçleri (List Comprehensions)

Şimdi Python’daki listelere ilişkin çok önemli bir konuya değineceğiz. Bu konunun adı ‘liste üreteçleri’. İngilizce’de buna “List Comprehension” adı veriliyor.

Adından da anlaşılacağı gibi, liste üreteçlerinin görevi liste üretmektir. Basit bir örnek ile liste üreteçleri konusuna giriş yapalım:

liste = [i for i in range(1000)]

Burada 0’dan 1000’e kadar olan sayıları tek satırda bir liste haline getirdik. Aslında yukarıdaki kod şu şekilde de yazılabilir:

liste = []

for i in range(1000):
    liste += [i]

Aynı iş için liste üreteçlerini kullandığımızda ise bu etkiyi çok daha kısa bir yoldan halletmiş oluyoruz.

Liste üreteçlerini kullandığımız kodu tekrar önümüze alalım:

liste = [i for i in range(1000)]

Gördüğünüz gibi, burada önceden boş bir liste tanımlamamıza gerek kalmadı. Şu kod:

for i in range(1000):
    liste += [i]

Liste üreteçlerini kullandığımızda şu koda dönüşüyor:

[i for i in range(1000)]

Örneğin 0 ile 1000 arasındaki çift sayıları listelemek için liste üreteçlerini kullanmak, alternatiflerine göre daha makul bir tercih olabilir:

liste = [i for i in range(1000) if i % 2 == 0]

Liste üreteçleri ile ilgili bir örnek daha verelim. Mesela elinizde şöyle bir liste olduğunu düşünün:

liste = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]

Burada iç içe geçmiş 4 adet liste var. Bu listenin bütün öğelerini tek bir listeye nasıl alabiliriz? Yani şöyle bir çıktıyı nasıl elde ederiz?

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for döngülerini kullanarak şöyle bir kod yazabiliriz:
liste = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]

tümü = []

for i in liste:
    for z in i:
        tümü += [z]

print(tümü)

Liste üreteçleri ise daha kısa bir çözüm sunar:

liste = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9],
         [10, 11, 12]]

tümü = [z for i in liste for z in i]
print(tümü)

Diyelim ki bir X.O.X Oyunu (Tic Tac Toe) yazıyorsunuz. X işaretinin oyunu kazanabilmesi için bu işaretin oyun tahtası üzerinde şu şekilde bir dizilime sahip olması gerekir:

 O   X   O

___  X   O

___  X  ___

Bu dizilime göre oyunu X işareti kazanır. Peki X işaretinin, oyunu kazanmasını sağlayacak bu dizilime ulaştığını nasıl tespit edeceksiniz?

Bunun için öncelikle oyun tahtası üzerinde hangi dizilim şekillerinin galibiyeti getireceğini gösteren bir liste hazırlayabilirsiniz.

Mesela yukarıdaki gibi 3×3 boyutundaki bir oyun tahtasında X işaretinin oyunu kazanabilmesi için şu dizilimlerden herhangi birine sahip olması gerekir:

[0, 0], [1, 0], [2, 0]

 X  ___  ___

 X  ___  ___

 X  ___  ___


[0, 1], [1, 1], [2, 1]

 ___  X  ___

 ___  X  ___

 ___  X  ___


[0, 2], [1, 2], [2, 2]

 ___  ___  X

 ___  ___  X

 ___  ___  X

[0, 0], [0, 1], [0, 2]

 X    X    X
___  ___  ___

___  ___  ___


[1, 0], [1, 1], [1, 2]

___  ___  ___

 X    X    X
___  ___  ___


[2, 0], [2, 1], [2, 2]

___  ___  ___

___  ___  ___

 X    X    X


[0, 0], [1, 1], [2, 2]

 X   ___  ___

 ___  X   ___

 ___  ___  X


 [0, 2], [1, 1], [2, 0]

 ___  ___  X

 ___  X  ___

 X  ___  ___

Aynı dizilimler O işareti için de geçerlidir. Dolayısıyla bu kazanma ölçütlerini şöyle bir liste içinde toplayabilirsiniz:

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 1], [1, 1], [2, 1]],
                     [[0, 2], [1, 2], [2, 2]],
                     [[0, 0], [0, 1], [0, 2]],
                     [[1, 0], [1, 1], [1, 2]],
                     [[2, 0], [2, 1], [2, 2]],
                     [[0, 0], [1, 1], [2, 2]],
                     [[0, 2], [1, 1], [2, 0]]]

Oyun sırasında X veya O işaretlerinin aldığı konumu bu kazanma ölçütleri ile karşılaştırarak oyunu kimin kazandığını tespit edebilirsiniz.

Yani kazanma_ölçütleri adlı liste içindeki, iç içe geçmiş listelerden herhangi biri ile oyunun herhangi bir aşamasında tamamen eşleşen işaret, oyunu kazanmış demektir.

Örneğin elinizde, yukarıda bahsettiğimiz kazanma ölçütlerini temsil eden şöyle bir liste olduğunu düşünün:

liste1 = [[1, 2, 3],
          [4, 5, 6],
          [7, 8, 9],
          [10, 11, 12],
          [13, 14, 15],
          [16, 17, 18],
          [19, 20, 21],
          [22, 23, 24],
          [25, 26, 27],
          [28, 29, 30],
          [31, 32, 33]]
Bir de şöyle bir liste:
liste2 = [1, 27, 88, 98, 50, 9, 28, 45, 54, 66, 61, 23, 10, 33,
          22, 12, 6, 99, 63, 26, 87, 25, 77, 5, 16, 93, 99, 44,
          59, 69, 34, 10, 60, 92, 61, 44, 5, 3, 23, 99, 79, 51,
          89, 63, 53, 31, 76, 41, 49, 10, 88, 63, 55, 43, 40, 71,
          16, 49, 78, 41, 35, 97, 33, 76, 25, 81, 15, 99, 64, 20,
          33, 6, 89, 81, 44, 53, 59, 75, 27, 15, 64, 36, 72, 78,
          34, 36, 20, 41, 41, 75, 56, 30, 86, 46, 9, 42, 21, 64,
          26, 52, 77, 65, 64, 12, 38, 1, 35, 20, 73, 71, 37, 35,
          72, 38, 100, 52, 16, 49, 79]

Burada amacınız liste1 içinde yer alan iç içe geçmiş listelerden hangisinin liste2 içindeki sayıların alt kümesi olduğunu,

yani liste2 içindeki sayıların, liste1 içindeki üçlü listelerden hangisiyle birebir eşleştiğini bulmak. Bunun için şöyle bir kod yazabiliriz:

for i in liste1:
    ortak = [z for z in i if z in liste2]
    if len(ortak) == len(i):
        print(i)

Bu kodlar ilk bakışta gözünüze çok karmaşık gelmiş olabilir. Ama aslında hiç de karmaşık değildir bu kodlar. Şimdi bu kodları Türkçe’ye çevirelim:

1. satır: liste1 adlı listedeki her bir öğeye i adını verelim

2. satır: i içindeki, liste2’de de yer alan her bir öğeye de z adını verelim ve bunları ortak adlı bir listede toplayalım.

3. satır: eğer ortak adlı listenin uzunluğu i değişkeninin uzunluğu ile aynıysa

4. satır: i’yi ekrana basalım ve böylece alt kümeyi bulmuş olalım.

Eğer bu satırları anlamakta zorluk çekiyorsanız okumaya devam edin. Biraz sonra vereceğimiz örnek programda da bu kodları görecek ve bu kodların ne işe yaradığını orada daha iyi anlayacaksınız.

Örnek Program: X.O.X Oyunu

Bu bölümde, Python programlama dilinde şimdiye kadar öğrendiklerimizi kullanarak X.O.X oyunu yazacağız.

Burada ilk yapmamız gereken şey, üzerinde oyun oynanacak tahtayı çizmek olmalı. Amacımız şöyle bir görüntü elde etmek:

___ ___ ___

___ ___ ___

___ ___ ___

Bu tahtada oyuncu soldan sağa ve yukarıdan aşağıya doğru iki adet konum bilgisi girecek ve oyunu oynayan kişinin gireceği bu konumlara “X” ve “O” harfleri işaretlenecek.

Böyle bir görüntü oluşturmak için pek çok farklı yöntem kullanılabilir.

Ama oyuncunun her konum bilgisi girişinde, X veya O işaretini tahta üzerinde göstereceğimiz için tahta üzerinde oyun boyunca sürekli birtakım değişiklikler olacak.

Bildiğiniz gibi karakter dizileri, üzerinde değişiklik yapmaya müsait bir veri tipi değil. Böyle bir görev için listeler daha uygun bir araç olacaktır. O yüzden tahtayı oluşturmada listeleri kullanmayı tercih edeceğiz.

tahta = [["___", "___", "___"],
         ["___", "___", "___"],
         ["___", "___", "___"]]

Gördüğünüz gibi, burada iç içe geçmiş üç adet listeden oluşan bir liste var. print(tahta) komutunu kullanarak bu listeyi ekrana yazdırırsanız listenin yapısı daha belirgin bir şekilde ortaya çıkacaktır:

[['___', '___', '___'], ['___', '___', '___'], ['___', '___', '___']]

Oyun tahtasını oluşturduğumuza göre, şimdi yapmamız gereken şey bu oyun tahtasını düzgün bir şekilde oyuncuya göstermek olmalı.

print("\n"*15)

for i in tahta:
    print("\t".expandtabs(30), *i, end="\n"*2)

Bu kodlarda bilmediğiniz hiçbir şey yok. Burada gördüğünüz her şeyi önceki derslerde öğrenmiştiniz.

print() fonksiyonunun ikinci parametresi ise *i. Bu parametrenin ne iş yaptığını anlamak için şöyle bir kod yazalım:

tahta = [["___", "___", "___"],
         ["___", "___", "___"],
         ["___", "___", "___"]]

for i in tahta:
    print(i)
Bu kodları çalıştırdığımızda şöyle bir çıktı elde ederiz:
['___', '___', '___']
['___', '___', '___']
['___', '___', '___']

Gördüğünüz gibi, iç içe geçmiş üç adet listeden oluşan tahta adlı liste içindeki bu iç listeler ekrana döküldü. Bir de şuna bakın:

tahta = [["___", "___", "___"],
         ["___", "___", "___"],
         ["___", "___", "___"]]

for i in tahta:
    print(*i)


Bu kodlar çalıştırıldığında şu çıktıyı verir:

___ ___ ___
___ ___ ___
___ ___ ___


Bu defa liste yapısını değil, listeyi oluşturan öğelerin kendisini görüyoruz.

Şimdi yapmamız gereken şey, oyundaki kazanma ölçütlerini belirlemek.

Mesela oyun sırasında şöyle bir görüntü ortaya çıkarsa hemen oyunu durdurup “O KAZANDI!” gibi bir çıktı verebilmemiz lazım:

 O   O   O

___  X   X

___ ___ ___

Veya şöyle bir durumda “X KAZANDI!” diyebilmeliyiz:

X   O  ___

X   O   O

X  ___ ___

Yukarıdaki iki örnek üzerinden düşünecek olursak, herhangi bir işaretin şu konumlarda bulunması o işaretin kazandığını gösteriyor:

yukarıdan aşağıya 0; soldan sağa 0
yukarıdan aşağıya 1; soldan sağa 0
yukarıdan aşağıya 2; soldan sağa 0

veya:

yukarıdan aşağıya 0; soldan sağa 0
yukarıdan aşağıya 0; soldan sağa 1
yukarıdan aşağıya 0; soldan sağa 2

İşte bizim yapmamız gereken şey, bir işaretin oyun tahtası üzerinde hangi konumlarda bulunması halinde oyunun biteceğini tespit etmek.

Yukarıdaki örnekleri göz önüne alarak bunun için şöyle bir liste hazırlayabiliriz:

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 0], [0, 1], [0, 2]]]

Burada iki adet listeden oluşan, kazanma_ölçütleri adlı bir listemiz var. Liste içinde, her biri üçer öğeden oluşan şu listeleri görüyoruz:

[[0, 0], [1, 0], [2, 0]]
[[0, 0], [0, 1], [0, 2]]

Burada her bir liste içindeki ilk sayı oyun tahtasında yukarıdan aşağıya doğru olan düzlemi; ikinci sayı ise soldan sağa doğru olan düzlemi gösteriyor.

Tabii ki oyun içindeki tek kazanma ölçütü bu ikisi olmayacak. Öteki kazanma ölçütlerini de tek tek tanımlamalıyız:

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 1], [1, 1], [2, 1]],
                     [[0, 2], [1, 2], [2, 2]],
                     [[0, 0], [0, 1], [0, 2]],
                     [[1, 0], [1, 1], [1, 2]],
                     [[2, 0], [2, 1], [2, 2]],
                     [[0, 0], [1, 1], [2, 2]],
                     [[0, 2], [1, 1], [2, 0]]]
İki farklı liste daha tanımlamamızda fayda var:
x_durumu = []
o_durumu = []

Bu değişkenler sırasıyla X işaretinin ve O işaretinin oyun içinde aldıkları konumları kaydedecek.

Mesela oyuna 0 işareti ile başlanacaksa, 0 işaretinin yerleştirilmesinden sonra sıranın X işaretine geçmesi gerekiyor.

X işareti de yerleştirildikten sonra sıra tekrar 0 işaretine geçmeli ve oyun süresince bu böyle devam edebilmeli.

Bu sürekliliği sağlamak için şöyle bir kod yazabiliriz:

sıra = 1

while True:
    if sıra % 2 == 0:
        işaret = "X".center(3)
    else:
        işaret = "O".center(3)

    sıra += 1

    print()
    print("İŞARET: {}\n".format(işaret))

Burada sayıların tek veya çift olma özelliğinden yararlanarak X ve O işaretleri arasında geçiş yaptık. Önce sıra adlı bir değişken tanımlayıp bunun değerini 1 olarak belirledik. 

while döngüsünde ise bu değişkenin değerini her defasında 1 artırdık. Eğer sayının değeri çiftse işaret X; tekse O olacak.

Bu arada X ve O adlı karakter dizilerini, center() metodu yardımıyla ortaladığımıza dikkat edin.

while döngümüzü yazmaya devam edelim:

x = input("yukarıdan aşağıya [1, 2, 3]: ".ljust(30))
if x == "q":
    break

y = input("soldan sağa [1, 2, 3]: ".ljust(30))
if y == "q":
    break

x = int(x)-1
y = int(y)-1

Burada X veya O işaretlerini tahta üzerinde uygun yerlere yerleştirebilmek için kullanıcının konum bilgisi girmesini istiyoruz. 

x değişkeni yukarıdan aşağıya doğru olan düzlemdeki konumu, y değişkeni ise soldan sağa doğru olan düzlemdeki konumu depolayacak. Oyunda kullanıcının girebileceği değerler 1, 2 veya 3 olacak.

Mesela oyuncu O işareti için yukarıdan aşağıya 1; soldan sağa 2 değerini girmişse şöyle bir görüntü elde edeceğiz:

___  O  ___

___ ___ ___

___ ___ ___

Kullanıcıdan gerekli konum bilgilerini aldığımıza göre, bu bilgilere dayanarak X ve O işaretlerini oyun tahtası üzerine yerleştirebiliriz.

print("\n"*15)

if tahta[x][y] == "___":
    tahta[x][y] = işaret
    if işaret == "X".center(3):
        x_durumu += [[x, y]]
    elif işaret == "O".center(3):
        o_durumu += [[x, y]]
    sıra += 1
else:
    print("\nORASI DOLU! TEKRAR DENEYİN\n")

Burada öncelikle 15 adet satır başı karakteri basıyoruz. Böylece oyun tahtası için ekranda boş bir alan oluşturmuş oluyoruz.

Bu satır tamamen güzel bir görüntü elde etmeye yönelik bir uygulamadır.

İkinci satırda gördüğümüz if tahta[x][y] == "___": kodu, oyun tahtası üzerindeki bir konumun halihazırda boş mu yoksa dolu mu olduğunu tespit etmemizi sağlıyor.

Oyun tahtası üzerinde değişiklik yapabilmek için nasıl bir yol izlediğimize dikkat edin:

tahta[x][y] = işaret

Mesela oyuncu yukarıdan aşağıya 1; soldan sağa 2 sayısını girmişse, kullanıcıdan gelen sayılardan 1 çıkardığımız için, Python yukarıdaki kodu şöyle değerlendirecektir:

tahta[0][1] = işaret
Ayrıca yukarıdaki kodlarda şu satırları da görüyoruz:
if işaret == "X".center(3):
    x_durumu += [[x, y]]
elif işaret == "O".center(3):
    o_durumu += [[x, y]]

Eğer işaret sırası X’te ise oyuncunun girdiği konum bilgilerini x_durumu adlı değişkene, eğer işaret sırası O’da ise konum bilgilerini o_durumu adlı değişkene yolluyoruz.

İsterseniz şimdiye kadar yazdığımız kodları şöyle bir topluca görelim:
tahta = [["___", "___", "___"],
         ["___", "___", "___"],
         ["___", "___", "___"]]

print("\n"*15)

for i in tahta:
    print("\t".expandtabs(30), *i, end="\n"*2)

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 1], [1, 1], [2, 1]],
                     [[0, 2], [1, 2], [2, 2]],
                     [[0, 0], [0, 1], [0, 2]],
                     [[1, 0], [1, 1], [1, 2]],
                     [[2, 0], [2, 1], [2, 2]],
                     [[0, 0], [1, 1], [2, 2]],
                     [[0, 2], [1, 1], [2, 0]]]

x_durumu = []
o_durumu = []

sıra = 1
while True:
    if sıra % 2 == 0:
        işaret = "X".center(3)
    else:
        işaret = "O".center(3)

    print()
    print("İŞARET: {}\n".format(işaret))

    x = input("yukarıdan aşağıya [1, 2, 3]: ".ljust(30))
    if x == "q":
        break

    y = input("soldan sağa [1, 2, 3]: ".ljust(30))
    if y == "q":
        break

    x = int(x)-1
    y = int(y)-1

    print("\n"*15)

    if tahta[x][y] == "___":
        tahta[x][y] = işaret
        if işaret == "X".center(3):
            x_durumu += [[x, y]]
        elif işaret == "O".center(3):
            o_durumu += [[x, y]]
        sıra += 1
    else:
        print("\nORASI DOLU! TEKRAR DENEYİN\n")

Gördüğünüz gibi epey kod yazmışız. Kodlarımızı topluca incelediğimize göre yazmaya devam edebiliriz:

for i in tahta:
     print("\t".expandtabs(30), *i, end="\n"*2)

Bu kodların ne işe yaradığınız biliyorsunuz. Oyun tahtasının son durumunu kullanıcıya göstermek için kullanıyoruz bu kodları.

Sıra geldi oyunun en önemli kısmına. Bu noktada oyunu kimin kazandığını belirlememiz gerekiyor.

for i in kazanma_ölçütleri:
    o = [z for z in i if z in o_durumu]
    x = [z for z in i if z in x_durumu]
    if len(o) == len(i):
        print("O KAZANDI!")
        quit()
    if len(x) == len(i):
        print("X KAZANDI!")
        quit()

Bu kodları anlayabilmek için en iyi yol uygun yerlere print() fonksiyonları yerleştirerek çıktıları incelemektir.

Mesela bu kodları şöyle yazarak o ve x değişkenlerinin değerlerini izleyebilirsiniz:

for i in kazanma_ölçütleri:
    o = [z for z in i if z in o_durumu]
    x = [z for z in i if z in x_durumu]
    print("o: ", o)
    print("x: ", x)
    if len(o) == len(i):
        print("O KAZANDI!")
        quit()
    if len(x) == len(i):
        print("X KAZANDI!")
        quit()

Bu kodlar içindeki en önemli öğeler o ve x adlı değişkenlerdir.

Burada, o_durumu veya x_durumu adlı listelerdeki değerlerle kazanma_ölçütleri adlı listedeki değerleri karşılaştırarak, ortak değerleri o veya x değişkenlerine yolluyoruz.

Eğer ortak öğe sayısı 3’e ulaşırsa (if len(o) == len(i): veya if len(x) == len(i):), bu sayıyı yakalayan ilk işaret hangisiyse oyunu o kazanmış demektir.

Kodlarımızın son hali şöyle oldu:
tahta = [["___", "___", "___"],
         ["___", "___", "___"],
         ["___", "___", "___"]]

print("\n"*15)

for i in tahta:
    print("\t".expandtabs(30), *i, end="\n"*2)

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 1], [1, 1], [2, 1]],
                     [[0, 2], [1, 2], [2, 2]],
                     [[0, 0], [0, 1], [0, 2]],
                     [[1, 0], [1, 1], [1, 2]],
                     [[2, 0], [2, 1], [2, 2]],
                     [[0, 0], [1, 1], [2, 2]],
                     [[0, 2], [1, 1], [2, 0]]]

x_durumu = []
o_durumu = []

sıra = 1
while True:
    if sıra % 2 == 0:
        işaret = "X".center(3)
    else:
        işaret = "O".center(3)

    print()
    print("İŞARET: {}\n".format(işaret))

    x = input("yukarıdan aşağıya [1, 2, 3]: ".ljust(30))
    if x == "q":
        break

    y = input("soldan sağa [1, 2, 3]: ".ljust(30))
    if y == "q":
        break

    x = int(x)-1
    y = int(y)-1

    print("\n"*15)

    if tahta[x][y] == "___":
        tahta[x][y] = işaret
        if işaret == "X".center(3):
            x_durumu += [[x, y]]
        elif işaret == "O".center(3):
            o_durumu += [[x, y]]
        sıra += 1
    else:
        print("\nORASI DOLU! TEKRAR DENEYİN\n")

    for i in tahta:
         print("\t".expandtabs(30), *i, end="\n"*2)

    for i in kazanma_ölçütleri:
        o = [z for z in i if z in o_durumu]
        x = [z for z in i if z in x_durumu]

        if len(o) == len(i):
            print("O KAZANDI!")
            quit()
        if len(x) == len(i):
            print("X KAZANDI!")
            quit()

Gördüğünüz gibi, sadece şu ana kadar öğrendiğimiz bilgileri kullanarak bir oyun yazabilecek duruma geldik. Dikkat ederseniz, yukarıdaki programda sadece karakter dizileri, sayılar, listeler ve birkaç fonksiyon var.

Nasıl sadece 7 nota ile müzik şaheserleri meydana getirilebiliyorsa, yalnızca 4-5 veri tipi ile de dünyayı ayağa kaldıracak programlar da yazılabilir.

Listeleri temel olarak incelediğimize göre biraz da demetlerden söz edebiliriz.

Demetler

Demetler, özellikle görünüş olarak listelere çok benzeyen bir veri tipidir. Bu veri tipi de, tıpkı listeler gibi, farklı veri tiplerini içinde barındıran kapsayıcı bir veri tipidir.

Demet Tanımlamak

Demet tanımlamanın birkaç farklı yolu vardır.

Nasıl karakter dizilerinin ayırt edici özelliği tırnak işaretleri, listelerin ayırt edici özelliği ise köşeli parantez işaretleri ise, demetlerin ayırt edici özelliği de normal parantez işaretleridir.

>>> demet = ("ahmet", "mehmet", 23, 45)

>>> type(demet)

<class 'tuple'>

Gördüğünüz gibi, karakter dizilerinin type() sorgusuna str, listelerin ise list cevabı vermesi gibi, demetler de type() sorgusuna tuple cevabı veriyor.

Yukarıdaki demeti şöyle de tanımlayabiliriz:

>>> demet = "ahmet", "mehmet", 23, 45

Gördüğünüz gibi, parantez işaretlerini kullanmadan, öğeleri yalnızca virgül işareti ile ayırdığımızda da elde ettiğimiz şey bir demet oluyor.

Demet oluşturmak için tuple() adlı bir fonksiyondan da yararlanabilirsiniz. Bu fonksiyon, liste oluşturan list() fonksiyonuna çok benzer:

>>> tuple('abcdefg')

('a', 'b', 'c', 'd', 'e', 'f', 'g')

Bu fonksiyonu kullanarak başka veri tiplerini demete dönüştürebilirsiniz:

>>> tuple(["ahmet", "mehmet", 34, 45])

('ahmet', 'mehmet', 34, 45)

Burada, [“ahmet”, “mehmet”, 34, 45] adlı bir listeyi tuple() fonksiyonu yardımıyla demete dönüştürdük.

Tek Öğeli bir Demet Tanımlamak

Tek öğeli bir karakter dizisi oluşturabilmek için şu yolu izliyorduk hatırlarsanız:

>>> kardiz = 'A'

Bu tek öğeli bir karakter dizisidir. Bir de tek öğeli bir liste tanımlayalım:

>>> liste = ['ahmet']

Bu da tek öğeli bir listedir. Gelin bir de tek öğeli bir demet oluşturmaya çalışalım:

>>> demet = ('ahmet')

Bu şekilde tek öğeli bir demet oluşturduğunuzu zannediyorsunuz, ama aslında oluşturduğunuz şey basit bir karakter dizisinden ibaret! Gelin kontrol edelim:

>>> type(demet)

<class 'str'>

Eğer tek öğeye sahip bir demet oluşturacaksak şöyle bir şey yazmalıyız:

>>> demet = ('ahmet',)

veya:

>>> demet = 'ahmet',

Gördüğünüz gibi, tek öğeli bir demet tanımlarken, o tek öğenin yanına bir tane virgül işareti yerleştiriyoruz.

Demetlerin Öğelerine Erişmek

Eğer bir demet içinde yer alan herhangi bir öğeye erişmek isterseniz, karakter dizileri ve listelerden hatırladığınız yöntemi kullanabilirsiniz:

>>> demet = ('elma', 'armut', 'kiraz')
>>> demet[0]

'elma'

>>> demet[-1]

'kiraz'

>>> demet[:2]

('elma', 'armut')

Gördüğünüz gibi, daha önce öğrendiğimiz indeksleme ve dilimleme kuralları aynen demetler için de geçerli.

Demetlerle Listelerin Birbirinden Farkı

Bu iki veri tipi arasındaki en önemli fark; listeler değiştirilebilir (mutable) bir veri tipi iken, demetler değiştirilemez (immutable) bir veri tipidir.

>>> demet = ('elma', 'armut', 'kiraz')
>>> demet[0] = 'karpuz'

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Gördüğünüz gibi, demetin herhangi bir öğesini değiştirmeye çalıştığımızda Python bize bir hata mesajı gösteriyor.

Ayrıca demetler üzerinde işlem yapmak listelere kıyasla daha hızlıdır.

Bir demetle başka bir demeti birleştirmek için o demeti yeniden tanımlamak da mümkündür:

>>> demet = ('ahmet', 'mehmet')
>>> demet = demet + ('selin',)

Asla unutmamalısınız: Python programlama dilinde sadece aynı tür verileri birbiriyle birleştirebilirsiniz. Mesela yukarıdaki örnekte ‘selin’ adlı öğeyi demet adlı demete bir karakter dizisi olarak ekleyemezsiniz:

>>> demet = demet + 'selin'

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "str") to tuple

Demetlerin Kullanım Alanı

Demetleri ilk öğrendiğinizde bu veri tipi size son derece gereksizmiş gibi gelebilir. Ama aslında oldukça yaygın kullanılan bir veri tipidir bu.

Özellikle programların ayar (conf) dosyalarında bu veri tipi sıklıkla kullanılır.

Örneğin Python tabanlı bir web çatısı (framework) olan Django’nun settings.py adlı ayar dosyasında pek çok değer bir demet olarak saklanır.

Mesela bir Django projesinde web sayfalarının şablonlarını (template) hangi dizin altında saklayacağınızı belirlediğiniz ayar şöyle görünür:

TEMPLATE_DIRS = ('/home/projects/djprojects/blog/templates',)

Burada, şablon dosyalarının hangi dizinde yer alacağını bir demet içinde gösteriyoruz.

Bu demet içine birden fazla dizin adı yazabilirdik. Ama biz bütün şablon dosyalarını tek bir dizin altında tutmayı tercih ettiğimiz için tek öğeli bir demet tanımlamışız.

Bu arada, daha önce de söylediğimiz gibi, demetlerle ilgili en sık yapacağınız hata, tek öğeli demet tanımlamaya çalışırken aslında yanlışlıkla bir karakter dizisi tanımlamak olacaktır.

Örneğin yukarıdaki TEMPLATE_DIRS değişkenini şöyle yazsaydık:

TEMPLATE_DIRS = ('/home/projects/djprojects/blog/templates')

Aslında bir demet değil, alelade bir karakter dizisi tanımlamış olurduk…

Bu eğitim seti Kaynak tarafından oluşturulmuştur.

İletişim: admin@herseymi.com
Yazı oluşturuldu 96

Bir Yorum Yazın

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.

Üste dön