Bu bölümde öğrendiğiniz bazı şeyler daha detaylı açıklanmakta ve bazı yeni konulara da değinilmekte.
Liste veri tipinin birkaç metodu daha var. İşte liste nesnelerinin bütün metodları:
append(x)
a[len(a):] = [x]
ifadesine denktir. .
extend(L)
a[
len(a):] = L
ifadesine denktir. .
insert(i, x)
a.insert(0, x)
ifadesi x'i listenin başına sokar, ve
a.insert(len(a), x)
ifadesi a.append(x)
ifadesine
denktir.
remove(x)
x
olan ilk elemanı listeden siler. Böyle
bir öğe yok ise bu hatadır.
pop([i])
a.pop()
listedeki son elemanı siler
ve geri döndürür. (i etrafındaki kare parantezler bu
parametreanin seçimlik olduğunu belirtir. Bu notasyonu Python
belgelerinde sıkça görebilirsiniz.)
index(x)
x
olan elemanın indisini geri döndürür. Böyle
bir eleman yok ise bu hatadır.
count(x)
x
'in listede kaç adet bulunduğunu bulur ve bu değeri geri
döndürür.
sort()
reverse()
Liste metodlarının çoğunu kullanan bir örnek:
>>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.6, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.6] >>> a.sort() >>> a [-1, 1, 66.6, 333, 333, 1234.5]
Liste metodları listelerin kolayca yığın olarak kullanılmasını sağlarlar. Yığına son giren eleman ilk çıkar. Yığının üzerine eleman eklemek için append() ve en üstteki elemanı almak için indis belirtmeden pop() kullanılır. Örnek:
>>> yigin = [3, 4, 5] >>> yigin.append(6) >>> yigin.append(7) >>> yigin [3, 4, 5, 6, 7] >>> yigin.pop() 7 >>> yigin [3, 4, 5, 6] >>> yigin.pop() 6 >>> yigin.pop() 5 >>> yigin [3, 4]
Listeleri kuyruk olarak da kullanmak mümkün. Bir kuyrukta ilk eklenen
eleman ilk alınan elemandır (ilk giren ilk çıkar). Kuyruğun sonuna bir
eleman eklemek için append() kullanılır. Sıranın başından bir
eleman almak için ise 0
indisi ile pop() kullanılır.
Örnek:
>>> kuyruk = ["Ali", "Veli", "Deli"] >>> kuyruk.append("Küpeli") # Küpeli kuyrukta >>> kuyruk.append("Aylin") # Aylin kuyrukta >>> kuyruk.pop(0) 'Ali' >>> kuyruk.pop(0) 'Veli' >>> kuyruk ['Deli', 'Küpeli', 'Aylin']
Listelerle kullanıldığında çok faydalı olan yerşeik fonksiyonlar vardır: filter(), map(), ve reduce().
"filter(fonksiyon, sıra)" sıra içerisinden
fonksiyon(eleman)
ın doğru sonuç verdiği
elemanların bulunduğu (mümkünse aynı türden) bir sıra geri döndürür.
Örneğin, bazı asal sayıları hesaplamak için şöyle yapılabilir:
>>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23]
"map(fonksiyon, sıra)" sıranın her elemanı için
fonksiyon(sıra)
çağırır ve geri döndürülen
değerlerin oluşturduğu listeyi geri döndürür. Örneğin bazı sayıların
küplerini hesaplamak için şu yol izlenebilir:
>>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
map(fonksiyon, sıra)]
ifadesinde birden fazla sıra
da kullanılabilir; ancak bu durumda fonksiyon sıra sayısı kadar
argümana sahip olmalıdır. fonksiyon her sıranın uygun elemanını
bir argüman olarak alır; ancak sıralardan biri kısa ise eksik
elemanlar için fonksiyona None
argümanı geçirilir. Eğer
fonksiyon adı için de None
kullanılırsa argümanlarını
geri döndüren bir fonksiyon etkisi yaratılır.
Bu iki özel durumu birleştirerek "map(None, list1, list2)" ifadesi ile bir çift diziyi çiftlerden oluşan bir diziye çevirebiliriz. Örnek:
>>> sira = range(8) >>> def kare(x): return x*x ... >>> map(None, sira, map(kare, sira)) [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)]
"reduce(fonksiyon, sıra)" ifadesi tek bir değer geri döndürür. Bu değer şöyle elde edilir: iki argümanlı fonksiyona sıranin ilk iki elemanı argüman olarak verilir, sonra da elde edilen sonuç ile sıranin sonraki elemanı argüman olarak verilir,daha sonra yine elde edilen sonuç ile bir sonraki eleman fonksiyona verilir ve bu işlem bütün elemanlar için tekrarlanır. Örneğin 1'den 10'a kadar olan böyle toplanabilir:
>>> def topla(x,y): return x+y ... >>> reduce(topla, range(1, 11)) 55
Sırada sadece bir eleman var ise bunun değeri geri döndürülür; sıra boş ise bir istisna oluşur (exception).
Başlangıç değerini bildirmek için üçüncü bir argüman kullanılabilir. Bu durumda fonksiyona ilk olarak başlangıç değeri ve sıranın ilk elemanına uygulanır ve diğer elemanlar ile devam eder. Örnek:
>>> def sonuc(sira): ... def topla(x,y): return x+y ... return reduce(topla, sira, 0) ... >>> sonuc(range(1, 11)) 55 >>> sonuc([]) 0
Liste üreteçleri map(), filter() ve/veya lambda fonksiyonlarını kullanmadan liste yaratmanın kısa bir yoludur. Bu yolla yaratılan liste tanımı genellikle daha kolay anlaşılır olur. Bir liste üreteci bir ifade ve bir for döngüsü ile bunları izleyen sıfır ya da daha fazla for veya if ifadelerinden oluşur. Sonuç kendisini izleyen for ve if bağlamında değerlendirilen ifadeden oluşan bir listedir. Eğer ifade bir demete (değişmez liste [tuple]) dönüşecekse parantez içinde yazılmalıdır.
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit '] >>> [weapon.strip() for weapon in freshfruit] # elemanları saran boşlukların atıldığı yeni bir liste ['banana', 'loganberry', 'passion fruit'] >>> vec = [2, 4, 6] >>> [3*x for x in vec] [6, 12, 18] >>> [3*x for x in vec if x > 3] [12, 18] >>> [3*x for x in vec if x < 2] [] >>> [{x: x**2} for x in vec] # sözlüklerden oluşan bir liste [{2: 4}, {4: 16}, {6: 36}] >>> [[x,x**2] for x in vec] [[2, 4], [4, 16], [6, 36]] >>> [x, x**2 for x in vec] # hata - demet için parantez gerekir File "<stdin>", line 1, in ? [x, x**2 for x in vec] ^ SyntaxError: invalid syntax >>> [(x, x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3] >>> [vec1[i]*vec2[i] for i in range(len(vec1))] [8, 12, -54]
Liste üreteçlerinin for döngülerine benzer davranması için, döngü değişkenine yapılan atamalar üreteç dışında da görünürler:
>>> x = 100 # bu değişecek >>> [x**3 for x in range(5)] [0, 1, 8, 27, 64] >>> x 4 # range(5) için son değer >>
del deyimi ile bir listeden indisi verilen bir eleman silinebilir. Bu deyim ile bir listeden dilimler de silinebilir (bunu daha önce dilimlere boş bir liste atayarak yapmıştık). Örnek:
>>> a [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.6, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.6, 1234.5]
del değişkeni tamamen silmek için de kullanılabilir:
>>> del a
Bu aşamadan sonra a
ismine değinmek hatadır (aynı isme başka
bir değer atanana kadar). Daha sonra del için başka kullanım
alanları da göreceğiz.
Listelerin ve karakter dizilerinin indisleme ve dilimleme gibi pek çok ortak özellikleri olduğunu gördük. Bunlar sıra şeklindeki iki veri tipidirler. Python gelişmekte olan bir dil; diğer sıra şeklindeki veri tipleri de Python'a eklenebilir. demet de başka bir sıra şekilli standart veri tipidir .
Bir demet virgül ile ayrılmış birkaç değerden oluşur.
>>> t = 12345, 54321, 'merhaba!' >>> t[0] 12345 >>> t (12345, 54321, 'merhaba!') >>> # demetler iç içe kullanılabilirler : ... u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'merhaba!'), (1, 2, 3, 4, 5))
Gördüğünüz gibi çıktıda demetler daima parantez içinde görünürler; ki iç içe geçmiş demetler belli olsun. Demetler parantezli veya parantezsiz olarak yazılabilirler; ancak parantezler genelikle gereklidirler (özellikle de demet daha büyük bir ifadenin içinde geçiyorsa).
Demetlerin pekçok kullanım alanı var: (x,y) koordinat çifti, veri tabanındaki işçi kayıtları vb. gibi. Demetler de karakter dizileri gibi değerleri değiştirilemez veri tipleridir; bunların elemanlarına atama yapılamaz (fakat dilimleme ve birleştirme aracılığı ile bu etki sağlanabilir). Ayrıca değiştirilebilen elemanlardan oluşan demetler oluşturmak da mümkündür (örnek: listelerden oluşan bir demet).
Sıfır veya bir elemanlı demetlerin oluşturulması ile ilgili özel bir problem var: bunların ifade edilmesini sağlayan sözdizim biraz acayip. Boş demetler bir çift boş parantez ile ifade edilir. Tek elemanı olan bir demet için ise elemandan sonra bir virgül kullanılır (tek bir değeri parantez içine almak yeterli değildir). Çirkin ama etkili. Örnek:
>>> bos = () >>> tekOge = 'merhaba', # <--satır sonundaki virgüle dikkat >>> len(bos) 0 >>> len(tekOge) 1 >>> tekOge ('merhaba',)
t = 12345, 54321, 'merhaba!'
ifadesi demetleme (tuple
packing) işlemine bir örnektir: 12345
, 54321
ve
'merhaba!'
değerleri bir demet içinde toplanmışlardır. Bu
işlemin tersi de mümkün:
>>> x, y, z = t
Doğal olarak, buna demet açma(sequence unpacking) deniyor . Demet açma sol taraftaki değişken sayısının sıra içindeki öğe sayısına eşit olmasını gerektirir. Çoklu değer atama işleminin aslında demetleme ve demet açmanın bir bileşimi olduğuna dikkat edin.
Burada küçük bir asimetri var: birden fazla değeri demetleme her zaman bir demet oluşturur ve demet açma herhangi bir sıra için yapılabilir. Örnek:
>>> paket = 'xyz' # bir karakter dizisi >>> a,b,c = paket >>> a 'x' >>> b 'y' >>> c 'z'
Python'da bulunan bir diğer faydalı veri tipi de sözlüktür. Sözlükler diğer programlama dillerinde ``çağrışımlı bellek'' ( associative memory) veya ``çağrışımlı dizi'' (associative array) olarak bilinirler. Sayılarla indislenen sıralardan farklı olarak, sözlükler anahtarlar (key) ile indislenirler. Anahtar değiştirilemeyen tipdeki herhangi bir veri tipinde olabilir. Sayılar ve karakter dizileri her zaman anahtar olabilirler. Demetler de sayılar, karakter dizileri veya demetler içerdikleri sürece anahtar olabilirler. Bir demet doğrudan ya da dolaylı olarak değiştirilebilir bir nesne içeriyorsa anahtar olarak kullanılamaz. Listeler anahtar olamazlar, çünkü append() ile extend() metodları, dilimleme ve indise değer atama ile değiştirilebilirler.
Bir sözlük anahtar : değer çiftlerinden oluşur. Bir anahtar
sözlükte sadece bir defa bulunabilir. Bir çift çengelli parantez boş
bir sözlük yaratır : {}
. Çengelli parantezlerin içine
virgülle ayrılmış anahtar : değer çiftleri koymak anahtar ve
değer çiftlerine ilk değerlerini verir. Çıktıya da sözlükler aynı
şekilde yazılırlar.
Sözlüklerle ilgili ana işlemler bir değerin bir anahtar ile saklanması
ve anahtar verildiğinde değerin bulunmasıdır. del
kullanarak
bir anahtar : değer çiftini silmek mümkündür. Zaten mevcut olan
bir anahtar kullanarak bir değer eklerseniz bu anahtarla bağlantılı
eski değer unutulur. Mevcut olmayan bir anahtar ile değer istemek
hatalıdır.
Sözlük nesnesinin keys()
metodu listedeki bütün anahtarların
listesini rasgele sıralı olarak geri döndürür (sıralamak isterseniz
listenin sort()
metodundan faydalanabilirsiniz) . Bir anahtarın
sözlükte olup olmadığını görmek için sözlüğün has_key()
metodu
kullanılır.
İşte sözlük kullanan küçük bir örnek:
>>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'guido': 4127, 'irv': 4127, 'jack': 4098} >>> tel.keys() ['guido', 'irv', 'jack'] >>> tel.has_key('guido') 1
dict() fonksiyonu anahtar-değer çiftlerinden oluşan demetlerden sözlükler üretir. Çiftlerin bir kalıba uyduğu durumlarda, liste üreteçleri ile anahtar-değer çiftleri kısaca ifade edilebilir.
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127} >>> dict([(x, x**2) for x in vec]) # liste üreteci kullanarak {2: 4, 4: 16, 6: 36}
Sözlükler üzerinde döngüler kurarken o anki değer items() metodu ile aynı anda elde edilebilir.
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.items(): ... print k, v ... gallahad the pure robin the brave
Bir sıra üzerinde dönerken konum indisi ve ona karşılık gelen değer de enumerate() fonksiyonunu kullanarak aynı anda elde edilebilir.
>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i, v ... 0 tic 1 tac 2 toe
Aynı anda iki sıra üzerinde ilerlemek için ise zip() fonksiyonu ile bunlar çiftler haline getirilebilir.
>>> sorular = ['adın', 'görevin', 'favori rengin'] >>> cevaplar = ['Adnan', 'Uyumak', 'Mavi'] >>> for s, c in zip(sorular, cevaplar): ... print 'Senin %s ne? %s.' % (s, c) ... Senin adın ne? Adnan. Senin görevin ne? Uyumak. Senin favori rengin ne? Mavi.
while
ve if
deyimlerinde kıyaslama dışında da
işleçler kullanılabilir.
in
ve not in
kıyaslama işleçleri bir değerin bir sıra
içinde olup olmadığını sınarlar. is
ve is not
isleçleri iki nesnenin tamamen aynı nesne olup olmadıklarını
sınarlar (bu sadece liste gibi değiştirilebilir nesnelerde önemlidir).
Bütün kıyaslama isleçleri aynı önceliğe sahiptirler ve bu sayısal
isleçlerinkinden düşüktür.
Kıyaslamalar zincirlenebilir: a < b == c
gibi.
Kıyaslamalar mantıksal isleçler and
ve
or
ile ile birleştirilebilirler, ve kıyaslamanın sonucu (ya da
herhangi bir mantıksal ifade) not
ile değillenebilirler.
Bunların
hepsi de kıyaslama isleçlerinden düşük önceliğe sahiptirler ve
aralarında en yüksek öncelikli olan not
ve en düşük öncelikli
olan or
islecidir. Örneğin A and not B or C
ifadesi
(A and (not B)) or C
ifadesine eştir. İstenen bileşimi elde
etmek için parantezler kullanılabilir.
and
ve or
mantıksal isleçlerine kısa devre
isleç de denir. Bunların argümanları soldan sağa değerlendirilir ve
sonuç belli olur olmaz değerlendirme işlemi kesilir. Örneğin A
ve C
doğru, fakat B
yanlış olsun. A and B and C
ifadesinde C ifadesi değerlendirilmez (çünkü C
nin değeri
sonucu değiştirmez). Genel olarak bir kısa devre isleci Bool değil
de genel bir değer gibi kullanıldığında en son değerlendirilen
argümanın değeri geri döndürülür.
Bir kıyaslamanın ya da mantıksal ifadenin sonucunu bir değişkene atamak mümkündür:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim'
C dilinin tersine, Python'da ifadelerin içinde atama olamayacağına
dikkat edin. C programcıları bundan şikayetçi olabilirler; ancak bu C
programlarında sık karşılaşılan bazı hataları engellemektedir
(==
yerine =
yazmak gibi).
Sıra nesneleri yine sıra şeklindeki diğer nesnelerle kıyaslanabilirler. Önce ilk iki eleman kıyaslanır. Bunlar farklı ise sonuç belli olmuştur; eşit olmaları halinde sonraki iki eleman kıyaslanır ve sıralardan biri tükenene kadar bu işlem tekrarlanır. Eğer kıyaslanan iki öğe de sıra ise bunlar da kendi aralarında kıyaslanırlar. İki sıranın bütün öğeleri aynı bulunursa bu sıralar eşit kabul edilir. Eğer bir sıra diğerinin başından bir kısmı ile aynı ise kısa olan sıra küçük kabul edilir. Karakterlerin kıyaslanmasında ASCII karakter sırası kullanılır. Aynı türden sıraların kıyaslanmasına bazı örnekler :
(1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
Farklı türden nesnelerin kıyaslanmasının yasal olduğuna dikkat edin. Türler alfabetik sırayla dizilmiştir (ingilizce isimlerine göre). Yani: liste < karakter dizisi < demet (list < string < tuple). 5.1