Seri Veri Türleri

Giriş

Endless Python

Seriler nümerik değerler, atamalar, dosyalar, olaylar ve istisnaların yanında, gömülü veri türlerinden biridir. Python altı seri (ya da sıralı) veri türü sunar:

• karakter dizileri
• bayt serileri
• bayt dizileri
• listeler
• demetler
• aralık nesneleri

Karakter dizileri, listeler, demetler, baytlar ve aralık nesneleri çok farklı şeyler gibi görünebilir ancak yine de aşağıda belirttiğimiz ortak özellikleri vardır:

• Karakter dizilerinin, listelerin ve demetlerin elemanları tanımlı bir sıraya göre dizilmiştir
• Elementlere indis kullanarak erişilebilir.
In [1]:
text = "Listelere ve Karakter Dizilerine indisler üzerinden erişilebilir!"
print(text[0], text[11], text[-1])      
L e !

Listelere erişmek:

In [2]:
lst = ["Viyana", "Londra", "Paris", "Berlin", "Zürih", "Hamburg"]
print(lst[0])
Viyana
In [3]:
print(lst[2])
Paris
In [4]:
print(lst[-1])
Hamburg

Başka programlama dillerinden farklı olarak, Python sıralı veri türleri üzerinde çalışmak üzere aynı sözdizimi ve fonksiyon adlarını kullanır. Örneğin, bir listenin, karakter dizisinin ve demetin uzunluğu len() isimli fonksiyonla bulunabilir:

In [1]:
ülkeler = ["Almanya","İsviçre","Avusturya","Fransa","Belçika", "Hollanda", "İngiltere"]
len(ülkeler)
Out[1]:
7
In [6]:
fib = [1,1,2,3,5,8,13,21,34,55]
len(fib)
Out[6]:
10

Baytlar

Bayt nesnesi küçük tamsayılardan oluşan bir seridir. Bir bayt nesnesinin elemanları 0-255 arasında yer alır, ASCII karakterlere karşılık gelir ve bu şekilde yazdırılır.

Python Listeleri

Şu ana kadar bazı listeler kullandık, ancak listelere düzgün bir giriş yapmadık. Listeler C, C++ veya Java gibi dillerin dizilerine benzer yapılardır, ancak Python listeleri “klasik” dizilerden çok daha esnek ve güçlüdür. Örneğin bir listedeki unsurların hepsinin aynı türden olması gerekmez. Bunun dışında, listeler bir program çalışırken değişebilir, C’de ise bir dizinin boyutu derleme zamanında sabitlenmiş olmalıdır.

Genel olarak konuşmak gerekirse liste bir nesne koleksiyonudur. Python’daki bir liste unsurların veya elemanların sıralanmış bir grubudur. Bu liste elemanlarının aynı türden olmasına gerek olmadığını belirtmek isteriz. Sayılar, karakter dizileri, diğer listeler vb., eleman karışımı olabilir. Python betikleri ve programları için liste türü çok elzemdir, yani içinde liste olmayan bir Python programı bulmak pek muhtemel değil.

Python listelerinin temel özellikleri:

• Sıralıdır
• Rastgele nesneler içebilir
• Listenin elemanlarına indeks ile erişilebilir,
• İstenirse iç içe geçirilebilir, yani alt listeler olarak başka listeler içerebilir
• Boyutları değişkendir
• Değişebilir, yani bir listenin elemanları değiştirilebilir.

Liste Notasyonu ve Örnekler

Liste nesneleri köşeli parantezle kapatılır ve virgüller ile ayrılır. Aşağıdaki tabloda listelerin bazı örneklerini bulabilirsiniz:

Liste Açıklama
[] Boş bir liste
[1,1,2,3,5,8] Tamsayıları içeren bir liste
[42, "Soru ne?", 3.1415] Farklı veri türleri içeren bir liste
["Stuttgart", "Freiburg", "München", "Nürnberg", "Würzburg", "Ulm","Friedrichshafen", Zürich", "Wien"] Karakter dizileri içeren bir liste
[["London","England", 7556900], ["Paris","France",2193031], ["Bern", "Switzerland", 123466]] İç içe geçmiş bir liste
["High up", ["further down", ["and down", ["deep down", "the answer", 42]]]] Derin iç içe geçmiş bir liste

Liste Elemanlarına Erişim

Bir değişkene liste atamak:

diller = ["Python", "C", "C++", "Java", "Perl"]
Bir listenin elemanlarına erişimin değişik yolları vardır. C programcıları için en kolay yöntem muhtemelen indisler üzerinden olur, yani listelerin numaraları 0’dan başlayarak numaralandırılır:

In [7]:
diller = ["Python", "C", "C++", "Java", "Perl"]
print(diller[0] + " ve " + diller[1] + " çok farklıdır!") 
Python ve C çok farklıdır!
In [8]:
print("Listenin son öğesine ulaşıyorum: : " + diller[-1]) 
Listenin son öğesine ulaşıyorum: : Perl

Yukarıdaki örnekler aynı veri türlerine sahip öğelerin bulunduğu listeler. Ama daha önce yaptığımız gibi, listelerin çeşitli veri türleri de olabilir. Aşağıdaki örnek bunu gösteriyor:

grup = ["Ali", 23, "Ayşe", 72, "Fatma", 29]

Alt listeler

Listelerin öğe olarak alt listeleri olabilir. Bu alt listeler de alt listelere sahip olabilir, yani listeler alt list yapıları ile özyinelemeli olarak oluşturulabilir.

In [2]:
kişi = [["Murat","Yıldırım"],["17, Atatürk Caddesi", "12345","Ankara"],"07876-7876"]
ad_soyad = kişi[0]
print(ad_soyad)
['Murat', 'Yıldırım']
In [3]:
ad = kişi[0][0]
print(ad)
Murat
In [4]:
soyad = kişi[0][1]
print(soyad)
Yıldırım
In [6]:
adres = kişi[1]
cadde = kişi[1][0]
print(cadde)
17, Atatürk Caddesi

Sonraki örnekte derin yapılı ve karmaşık bir liste göreceğiz:

In [14]:
karmaşık_liste = [["a",["b",["c","x"]]]]
karmaşık_liste = [["a",["b",["c","x"]]],42]
karmaşık_liste[0][1]
Out[14]:
['b', ['c', 'x']]
In [15]:
karmaşık_liste[0][1][1][0]
Out[15]:
'c'

Listeleri değiştirmek

In [16]:
diller = ["Python", "C", "C++", "Java", "Perl"]
diller[4] = "Lisp"
diller
Out[16]:
['Python', 'C', 'C++', 'Java', 'Lisp']
In [17]:
diller.append("Haskell")
diller
Out[17]:
['Python', 'C', 'C++', 'Java', 'Lisp', 'Haskell']
In [18]:
diller.insert(1, "Perl")
diller
Out[18]:
['Python', 'Perl', 'C', 'C++', 'Java', 'Lisp', 'Haskell']
In [19]:
alışveriş_listesi = ['süt', 'yoğurt', 'yumurta', 'tereyağ', 'ekmek', 'muz']

Sanal bir markete gidiyoruz. Sepetinizi kapın ve alışverişe başlayın:

In [7]:
alışveriş_listesi = ['süt', 'yoğurt', 'yumurta', 'tereyağ', 'ekmek', 'muz']
sepet = []
#  "pop()"" listedeki son ögeyi siler ve bunu (geri) döndürür.
öge = alışveriş_listesi.pop() 
print(öge, alışveriş_listesi)
sepet.append(öge)
print(sepet)
muz ['süt', 'yoğurt', 'yumurta', 'tereyağ', 'ekmek']
['muz']
In [8]:
# böyle devam ediyoruz:
öge = alışveriş_listesi.pop() 
print("alışveriş_listesi:", alışveriş_listesi)
sepet.append(öge)
print("sepet: ", sepet)
alışveriş_listesi: ['süt', 'yoğurt', 'yumurta', 'tereyağ']
sepet:  ['muz', 'ekmek']

Ve bir while loop ile:

In [23]:
alışveriş_listesi = ['süt', 'yoğurt', 'yumurta', 'tereyağ', 'ekmek', 'muz']
sepet = []
while alışveriş_listesi != []:
    öge = alışveriş_listesi.pop()  
    sepet.append(öge)
    print(öge, alışveriş_listesi, sepet)

print("alışveriş_listesi:", alışveriş_listesi)
print("sepet: ", sepet)
muz ['süt', 'yoğurt', 'yumurta', 'tereyağ', 'ekmek'] ['muz']
ekmek ['süt', 'yoğurt', 'yumurta', 'tereyağ'] ['muz', 'ekmek']
tereyağ ['süt', 'yoğurt', 'yumurta'] ['muz', 'ekmek', 'tereyağ']
yumurta ['süt', 'yoğurt'] ['muz', 'ekmek', 'tereyağ', 'yumurta']
yoğurt ['süt'] ['muz', 'ekmek', 'tereyağ', 'yumurta', 'yoğurt']
süt [] ['muz', 'ekmek', 'tereyağ', 'yumurta', 'yoğurt', 'süt']
alışveriş_listesi: []
sepet:  ['muz', 'ekmek', 'tereyağ', 'yumurta', 'yoğurt', 'süt']

Demetler

Bir demet değiştirilemeyen bir listedir, yani oluşturulduktan sonra hiçbir şekilde değiştirilemez. Bir demet, listelerle benzeşir ancak öğeler köşeli parantezler yerine normal parantezler arasına alınır. İndeks kullanımı listelerle aynıdır. Bir demet oluşturulduğu zaman ona öğe eklenemez ve ondan öğe çıkartılamaz. Peki demetler neden kullanılır?

• Demetler listelerden daha hızlı çalışır. 
• Bazı verilerin değişmemesi gerektiğini düşünüyorsanız, listeler yerine demetler kullanmalısınız, çünkü bu veri türü verilerinizi kaza eseri oluşacak değişmelere karşı korur. 
• Demetlerin temel avantajı, bunların sözlüklerde anahtar değer olarak kullanılabilmesidir, ancak listeler bunu yapamaz. 

Aşağıdaki örneklerde bir demetin nasıl tanımlanacağını ve ona nasıl erişileceğini göreceğiz. Ayrıca bir demetin öğesine yeni bir değer atamaya çalıştığımızda hata oluşacağını da göreceğiz:

In [24]:
t = ("demetler", "değiştirilmez")
t[0]
Out[24]:
'demetler'
In [25]:
t[0]="öğelere atama yapmak mümkün değildir"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-7440a3a19221> in <module>
----> 1 t[0]="öğelere atama yapmak mümkün değildir"

TypeError: 'tuple' object does not support item assignment

Dilimleme

Pek çok programlama dilinde bir karakter dizisinin bir kısmını dilimlemek oldukça zordur ve daha da zor olanı, “alt dizi” adreslemesi yapmak isterseniz ortaya çıkar. Python dilimleme operatörü ile bu işi sizin için kolaylaştırır. Dilimleme sıklıkla, “substring”, “gstr” veya “substr” gibi olası adlarla bir fonksiyon olarak sunulur.

Bir karakter dizisinin veya listenin bir kısmını almak istediğiniz her an Python’daki dilimleme operatörü kullanırsınız. Sözdizimi basittir. Gerçekten de bir indekse sahip tek bir öğeye erişmeye biraz benzer, ancak bir sayı yerine iki nokta üst üste (:) işareti ile ayrılır. Bir başlangıç ve bir de bitiş indeks değeri kullanılır, bunlardan biri veya ikisi de yazılmayabilir. Dilimlemenin nasıl işlediğini anlamak için aşağıdaki örneklere bakalım:

In [26]:
str = "Python harikadır"
ilk_altı = str[0:6]
ilk_altı
Out[26]:
'Python'
In [27]:
beşten_başla = str[5:]
beşten_başla
Out[27]:
'n harikadır'
In [28]:
bir_kopya = str[:]
son_beşli_olmadan = str[0:-5]
son_beşli_olmadan
Out[28]:
'Python hari'

Sözdizimsel olarak listelerde bir fark yoktur. Şimdi Avrupa şehir isimlerini girdiğimiz örneğe geri dönelim:

In [29]:
şehirler = ["Viyana", "Londra", "Paris", "Berlin", "Zürih", "Hamburg"]
ilk_üç = şehirler[0:3]
# daha kolayı:
ilk_üç = şehirler[:3]
print(ilk_üç)
['Viyana', 'Londra', 'Paris']

Şimdi son ikisi olmadan, diğer şehirlerimizi seçelim, yani “Zürih” ve “Hamburg”’u hariç tutalım:

In [30]:
son_ikisi_hariç_hepsi = şehirler[:-2]
print(son_ikisi_hariç_hepsi)
['Viyana', 'Londra', 'Paris', 'Berlin']

Dilimleme üç argüman ile de çalışır. Üçüncü argüman 3 ise, karakter dizisinden veya demetten ilk ile son değer arasında üçer üçer gidilerek alınır.

Bir sıralı veri türü olarak s alınırsa bu şöyle çalışır:

s[başlangıç: son: adım]
Sonuçtaki sıra aşağıdaki öğeleri içerir:

s[başlangıç], s[başlangıç+ 1 * adım], ... s[başlangıç+ i * adım] hepsi için (başlangıç + i * adım) < son. 
Aşağıdaki örnekte bir karakter dizisi tanımlıyoruz ve bu karakter dizisinin her üçüncü karakterini görüyoruz:

In [9]:
str = "Python Linux'ta çok iyi çalışır"
str[::3]
Out[9]:
"Ph n' kyçır"

Aşağıdaki kelime salatası olarak görülen dizi iki cümle içeriyor. Birincisi Kanada’daki Python derslerimde kullandığım örtülü reklam: "TPoyrtohnotno ciosu rtshees lianr gTeosrto nCtiot yb yi nB oCdaennasdeao"

Bunu adım argümanı kullanarak dilimlemeyi deneyin. Çözümü sadece iki adım!

In [32]:
s = "TPoyrtohnotno  ciosu rtshees  lianr gTeosrto nCtiot yb yi nB oCdaennasdeao"
print(s)
TPoyrtohnotno  ciosu rtshees  lianr gTeosrto nCtiot yb yi nB oCdaennasdeao
In [33]:
s[::2]
Out[33]:
'Toronto is the largest City in Canada'
In [34]:
s[1::2]
Out[34]:
'Python courses in Toronto by Bodenseo'

Bu karakter dizisini nasıl yaptığımızı merak etmiş olabilirsiniz. Aşağıda yazdıklarımızı anlamak için liste kapsamı tekniğini (list comprehension) kavramanız gerekecek:

In [35]:
s = "Toronto is the largest City in Canada"
t = "Python courses in Toronto by Bodenseo"
s = "".join(["".join(x) for x in zip(s,t)])
s
Out[35]:
'TPoyrtohnotno  ciosu rtshees  lianr gTeosrto nCtiot yb yi nB oCdaennasdeao'

Uzunluk

Meter Bir dizinin uzunluğu, örneğin bir listenin, bir karakter dizisinin veya bir demetin uzunluğu len() fonksiyonu ile bulunur. Karakter dizileri için karakter sayıları ölçülürken listeler ve demetler için öğe sayısı ölçülür ve alt listeler bir öğe olarak sayılır.

In [36]:
txt = "Merhaba Dünya"
len(txt)
Out[36]:
13
In [37]:
a = ["Swen", 45, 3.54, "Basel"]
len(a)
Out[37]:
4

Dizilerin Birleştirilmesi

Karakter katarı veya listeler gibi iki dizinin birleştirilmesi iki sayı eklemek kadar kolaydır. Operatör işareti bile aynıdır. Aşağıdaki örnek iki karakter dizisinin nasıl birleştirildiğini gösteriyor:

In [38]:
adınız = "Homer"
soy_adınız = "Simpson"
isim = adınız + " " + soy_adınız
print(isim)
Homer Simpson

Listeler için de olay basittir:

In [39]:
renkler1 = ["kırmızı", "yeşil","mavi"]
renkler2 = ["siyah", "beyaz"]
renkler = renkler1 + renkler2
print(renkler)
['kırmızı', 'yeşil', 'mavi', 'siyah', 'beyaz']

Artırma değeri verme işareti olan “+=” aritmetik atamalarda iyi bilinir, ancak dizilerde de çalışır.

s += t
Sözdizim açısından şununla aynıdır:

s = s + t
Ancak sadece sözdizim açısından aynıdır. Uygulama ise değişiktir. İlk durumda sol taraf sadece bir kere değerlendirilir. Arttırma komutları optimizasyon için değiştirilebilir nesnelere uygulanabilir.

Bir Öğenin Bir Listede Bulunup Bulunmadığını Sorgulama

Bir öğenin bir listede bulunup bulunmadığını kontrol etmek kolaydır. “in” veya “not in” operatörlerini bu amaçla kullanabiliriz. Aşağıdaki örnekte bu operatörün nasıl uygulanacağını gösteriyoruz:

In [40]:
abc = ["a","b","c","d","e"]
"a" in abc
Out[40]:
True
In [41]:
"a" not in abc
Out[41]:
False
In [42]:
"e" not in abc
Out[42]:
False
In [43]:
"f" not in abc
Out[43]:
True
In [44]:
"y" in str
Out[44]:
True
In [45]:
"x" in str
Out[45]:
True

Tekrarlamalar

Şimdiye kadar diziler için “+” operatörünün varlığını öğrendik. Ayrıca “*” operatörünün de olduğunu şimdi öğreniyoruz. Elbette iki dizi arasında bildiğimiz manada bir çarpma yoktur. “*” bir dizi ve bir tamsayı ile tanımlıdır, örneğin s n veya n s gibi. Bu, n tane birleştirmenin kısa yoludur denebilir:

str * 4
şununla aynıdır:

str + str + str + str
Başka örnekler:

In [46]:
3 * "xyz-"
Out[46]:
'xyz-xyz-xyz-'
In [47]:
"xyz-" * 3
Out[47]:
'xyz-xyz-xyz-'
In [48]:
3 * ["a","b","c"]
Out[48]:
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']

” için çoğaltma emri de bu amaçla kullanılabilir: s = n ile s = s * n aynıdır.

Tekrarlamadaki Gizli Tehlikeler

Önceki örneklerimizde tekrarlama operatörünü karakter dizilerinde ve düz listelerde kullanmıştık. Bunu girintili listelerde de kullanabiliriz:

In [49]:
x = ["a","b","c"]
y = [x] * 4
y
Out[49]:
[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]
In [50]:
y[0][0] = "p"
y
Out[50]:
[['p', 'b', 'c'], ['p', 'b', 'c'], ['p', 'b', 'c'], ['p', 'b', 'c']]

Repetitions with References

Bu sonuç Python programlamaya yeni başlayanlar için oldukça hayret vericidir. y değişkeninin ilk alt listesindeki ilk öğeye yeni bir değer atadık, yani y[0][0]'a ve y’nin bütün alt listelerindeki ilk değeri “otomatik olarak” değiştirmiş olduk. (y[1][0], y[2][0] ve y[3][0] gibi.) Bunun sebebi tekrarlama operatörü olan “* 4”ün x listesine dört başvuru yapmasıdır: ve y[0][0]’a yeni bir değer atarsak y’nin her öğesi değişmiş olur.