Karakter Dizileri¶
Dikkat ettiyseniz ilk dersten bu yana sürekli olarak karakter dizileri ile haşır neşir oluyoruz. Karakter dizileriyle bu kadar içli dışlı olmamız kesinlikle boşuna değil. Zira karakter dizileri Python’ın en önemli konularından biridir. Gerçi biz şu ana kadar karakter dizilerine ilişkin epey şey öğrendik. Ancak karakter dizileri konusunda henüz görmediğimiz, ama görmemiz gereken pek çok şey de var. İşte bizim bu bölümde amacımız, karakter dizileri hakkında daha önce öğrendiklerimizi bir yandan pekiştirirken, bir yandan da bu konu hakkında öğrenmemiz gerekenleri öğrenmek. Bu bölümde, karakter dizilerini ve bunların metotlarını/fonksiyonlarını derinlemesine inceleme fırsatı bulacağız.
Karakter Dizisi Nedir?¶
İsterseniz işe en başından başlayalım ve şu soruyu soralım kendimize: “Karakter dizisi nedir?”
Kabaca tarif etmek gerekirse, tırnak içinde gösterebileceğimiz her şey bir karakter dizisidir. Mesela şu bir karakter dizisidir:
>>> "elma"
Gördüğünüz gibi, Python’da bir karakter dizisi tanımlamak için çok özel bir işlem yapmanıza gerek yok. Karakter dizisi olmasını istediğiniz bir şeyi tırnak içine aldığınız anda o artık bir karakter dizisidir. İsterseniz bu durumu teyit edelim:
>>> type(elma)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'elma' is not defined
Gördüğünüz gibi, “elma” kelimesini tırnak işaretleri içine almadığımızda (ve eğer daha önce elma adlı bir değişken de tanımlamamışsak) Python bize yukarıdaki gibi bir hata mesajı gösterecektir. Bir de şuna bakın:
>>> type("elma")
<type 'str'>
Ama eğer “elma” kelimesini tırnak içine alırsak her şey bir anda değişir. Bu işlemi yaptığımız anda artık “elma” kelimesi Python açısından bir karakter dizisidir. “Eee, ne olmuş yani?” dediğinizi duyar gibiyim... Belki bu bilgi şu anda size pek fazla bir şey ifade etmemiş olabilir. Ancak ileride nesne tabanlı programlama konusunu incelerken bunun ne kadar önemli bir özellik olduğunu anlayacaksınız. Şimdilik biz yolumuza devam edelim.
Yukarıdaki komutun çıktısından da anladığımız gibi, Python’da karakter dizileri str kısaltmasıyla gösteriliyor. Bu ifade İngilizce string (karakter dizisi) kelimesinin kısaltmasıdır.
Peki bir veri tipinin karakter dizisi olup olmamasının ne önemi var?
Python’da program yazarken elimizdeki herhangi bir verinin tipini bilmek son derece önemlidir. Yani o anda elimizde olan şeyin mesela bir sayı mı yoksa karakter dizisi mi olduğunu bilmek, yazdığımız kodların düzgün çalışabilmesi açısından büyük önem taşır. Mesela şu örneğe bakalım:
# -*- coding: utf-8 -*-
with open("sayilar.txt", "w") as f:
for i in range(5):
f.write(i)
Bu kodlar çalışma sırasında hata verecektir. Çünkü range() fonksiyonu sayı üretir. Yani range() fonksiyonundan gelen veri tipi sayıdır. Dolayısıyla bu veri tipini doğrudan bu şekilde dosyaya yazdıramazsınız. Bu fonksiyondan gelen veri tipinin dosyaya yazdırılabilmesi için öncelikle karakter dizisine çevrilmesi gerekir:
# -*- coding: utf-8 -*-
with open("sayilar.txt", "w") as f:
for i in range(5):
f.write(str(i))
Burada str() fonksiyonundan yararlanarak, range() fonksiyonunun ürettiği sayıları birer karakter dizisine çevirdik ve ondan sonra bunları doğruca dosyaya yazdırdık.
Aynı şekilde, mesela raw_input() fonksiyonu ile kullanıcıdan aldığınız verilerin tipinin de birer karakter dizisi olduğunu bilmek çok önemlidir. Eğer bunu bilmezseniz şöyle bir kod yazma hatasına düşebilirsiniz:
# -*- coding: utf-8 -*-
sayi = raw_input("Bir sayı girin: ")
print "Girdiğiniz sayının karesi: ", sayi ** 2
Bu kodlar çalışma sırasında hata verecektir. Çünkü dediğimiz gibi, raw_input() fonksiyonu bize bir karakter dizisi verir. Eğer biz bu fonksiyonla sayı almak istiyorsak, buradan gelen karakter dizisini sayıya çevirmemiz gerekir:
# -*- coding: utf-8 -*-
sayi = raw_input("Bir sayı girin: ")
print "Girdiğiniz sayının karesi: ", int(sayi) ** 2
Burada int() fonksiyonunu kullanarak, raw_input()‘tan gelen karakter dizisini sayıya çevirdik. Burada elbette raw_input() fonksiyonundan gelen karakter dizisini dümdüz bir şekilde sayıya çevirmeye çalışmak iyi bir yöntem değildir. Python’da herhangi bir dönüştürme işlemi yaparken, bu işlem sırasında bazı hataların da ortaya çıkabileceğini hesaba katmamız gerekir. Mesela yukarıdaki örnekte kullanıcı sayı yerine bir harf girerse kodlarımız hata verecektir. Bu yüzden yukarıdaki gibi bir kod yazmamız gerektiğinde bu tür hatalara karşı önlem almamız gerekir:
# -*- coding: utf-8 -*-
def deger_hatasi():
return "Harf yerine sayı girmeyi deneyin!"
def sifir_uyarisi():
return "0 dışında bir sayı girin!"
sayi = raw_input("Bir sayı girin: ")
if sayi == "0":
print sifir_uyarisi()
quit()
try:
n = int(sayi)
print "Girdiğiniz sayının karesi: ", n ** 2
except ValueError:
print deger_hatasi()
Bu arada, bir sayının karesini almak için Python’daki pow() adlı bir fonksiyondan da yararlanabiliriz:
>>> print pow(12, 2)
144
pow() fonksiyonu bir sayının istediğimiz bir kuvvetini hesaplamamızı sağlar. Mesela yukarıdaki örnekte biz 12 sayısının 2. kuvvetini hesapladık. Eğer 12’nin 3. kuvvetini hesaplamak isteseydik şöyle bir şey yazardık:
>>> print pow(12, 3)
1728
Yukarıdaki iki örnek sırasıyla şununla eşdeğerdir: 122 ve 123
Tırnak Tipleri¶
Dediğimiz gibi, Python’da karakter dizilerini başka veri tiplerinden ayıran en önemli özellik, tırnak içinde gösterilmeleridir. Python, karakter dizisi tanımlarken kullanabileceğimiz tırnak tipleri konusunda bize birkaç farklı seçenek sunar. Karakter dizilerini tanımlarken tek tırnak, çift tırnak veya üç tırnak işaretlerinden yararlanabiliriz. Örneğin:
>>> kardiz = "elma"
Biz yukarıda tanımladığımız elma karakter dizisini çift tırnak ile gösterdik. Ama siz isterseniz bu karakter dizisini tek veya üç tırnak işaretlerini kullanarak da tanımlayabileceğinizi biliyorsunuz. Hemen bir kaç örnek verelim:
>>> "C Programlama Dili"
>>> 'Guido Van Rossum'
>>> """Monty Python"""
Bunların hepsi birer karakter dizisidir. Ancak daha önceki derslerimizden edindiğimiz tecrübeye göre, bir karakter dizisini tanımlarken kullanacağımız tırnak tipi konusunda bazı noktalara da dikkat etmemiz gerekiyor. Örneğin karakter dizisi içinde bir kesme işareti varsa, karakter dizisini tek tırnak işaretleri içinde göstermemiz bazı sorunlara yol açabilir. Mesela “Python’ın 3.x sürümleri” ifadesini bir karakter dizisi olarak tanımlamak istediğimizde, kullanacağımız tırnak tipini belirlerken ifade içinde geçen kesme işaretini de dikkate almamız gerekir. Eğer bu ifadeyi karakter dizisi olarak tanımlarken tek tırnak işaretlerini kullanırsak, “Python’ın” kelimesi içinde geçen kesme işareti karışıklığa sebep olacaktır:
>>> print 'Python'ın 3.x sürümleri'
Yukarıdaki gibi bir kullanımın hataya yol açacağını biliyorsunuz. Bu tür hataları önlemek için izleyebileceğimiz birkaç farklı yol var:
>>> print "Python'ın 3.x sürümleri"
Burada kesme işaretinin karakter dizisini başlatan ve bitiren tırnak işaretleriyle karışmasını önlemek için karakter dizisini tek tırnak yerine çift tırnak içinde gösterdik. Çift tırnak yerine üç tırnak da kullanabiliriz:
>>> print """Python'ın 3.x sürümleri"""
Bu kullanım da geçerli bir yoldur. Ama eğer mutlaka tek tırnak kullanmak istersek kaçış dizilerinden faydalanmamız gerektiğini önceki derslerimizde de söylemiştik:
>>> print 'Python\'ın 3.x sürümleri'
Peki bu tırnak tiplerinden hangisini kullanmak daha iyidir? Cevap: Hangisi işinize geliyorsa! Teknik olarak bu tırnak tiplerinden hangisini kullandığınızın hiç bir önemi yok. Yazdığınız karakter dizisini tanımlamada hata vermediği sürece herhangi bir tırnak tipini kullanabilirsiniz. Python camiasında özellikle tek ve çift tırnaklar oldukça yaygın bir şekilde kullanılır. Ancak tek tırnak işareti karakter dizisi içinde geçen kesme işaretleriyle karışabileceği için, eğer kaçış dizileriyle de uğraşmak istemiyorsanız, tek tırnak yerine çift tırnak işaretlerini kullanmak daha pratik olabilir. Üç tırnak işareti ise genellikle karakter dizisi tanımlamada pek kullanılmaz. Python programcıları, birden fazla satıra bölünecek karakter dizilerini daha rahat bir şekilde oluşturmamızı sağladığı için üç tırnak işaretlerini çoğunlukla belgelendirme dizilerini tanımlarken kullanır. Mesela:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def bir_fonksiyon(parametre):
"""Bu fonksiyonun herhangi bir işlevi
yoktur. Örnek olsun diye verilmiştir..."""
pass
Gördüğünüz gibi, burada üç tırnak işaretlerini belgelendirme dizisi oluşturmak maksadıyla kullandık. Çünkü üç tırnak, öteki tırnak tiplerinden farklı olarak bize birden fazla satıra bölünmüş karakter dizilerini kolayca gösterme imkanı verir. Dilerseniz bununla ilgili şöyle bir örnek daha verelim:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print """\
Falanca v0.1'e hoşgeldiniz. Programı şu
parametreleri kullanarak çalıştırabilirsiniz:
-v sürüm numarasını görüntüler
-h yardım belgesini görüntüler
-c program yazarları hakkında bilgi verir
"""
def bir_fonksiyon(parametre):
pass
Gördüğünüz gibi, üç tırnak sayesinde, karakter dizisini nasıl yazdıysak çıktı da aynı şekilde görünüyor... Aynı çıktıyı tek veya çift tırnakla elde etmek oldukça güçtür.
Karakter Dizilerini Birleştirmek¶
Python’la programlama maceranızda karakter dizileri ile en sık yapacağınız işlemlerden biri de karakter dizilerini birbiriyle birleştirmek olacaktır. Python’da karakter dizilerini birleştirmenin birden fazla yöntemi var:
>>> ad = "Fırat"
>>> soyad = "Özgül"
>>> ad_soyad = ad + soyad
>>> print ad_soyad
FıratÖzgül
Burada basitçe “+” işlecinden yararlanarak iki karakter dizisini birleştirdik. Ancak gördüğünüz gibi, burada iki karakter dizisi arasında boşluk yok. Ama tabii siz bu boşluğu kendiniz de ekleyebilirsiniz:
>>> bosluk = " "
>>> print ad + bosluk + soyad
Fırat Özgül
Bu yöntemi kullanarak şöyle bir şey yazabilirsiniz mesela:
>>> a = ""
>>> for i in range(10):
... a += str(i)
...
>>> print a
0123456789
Python’da karakter dizileri “değiştirilemeyen” (immutable) veri tipleridir. Yani karakter dizileri üzerinde değişiklik yapılamaz. Ama mesela listeler böyle değildir. Listeler değiştirilebilir (mutable) veri tipleri oldukları için listeler üzerinde değişiklik yapabiliyoruz. Bir örnek verelim:
>>> lst = ["elma", "armut", "muz"]
>>> lst.append("kiraz")
>>> print lst
["elma", "armut", "muz", "kiraz"]
Gördüğünüz gibi, oluşturduğumuz bir listeye append() metodunu kullanarak yeni bir öğe ekleyebildik. Ama karakter dizileri böyle değildir. Örneğin:
>>> kardiz = "elma"
>>> kardiz + "armut"
'elmaarmut'
Burada sanki karakter dizisi üzerinde değişiklik yapabilmişiz gibi görünüyor, ama aslında durum öyle değil:
>>> print kardiz
elma
Gördüğünüz gibi, özgün karakter dizisinde herhangi bir değişiklik olmadı. Özgün karakter dizisi hala “elma”... Eğer bir karakter dizisi üzerinde değişiklik yapmak istersek, özgün karakter dizisinin üzerine yazmamız veya değişiklikleri farklı bir karakter dizisi içinde depolamamız gerekir. Örneğin değişiklikleri farklı bir karakter dizisinde depolamak için şöyle bir şey yazabiliriz:
>>> kardiz2 = kardiz + "armut"
>>> print kardiz2
elmaarmut
Bu şekilde “elma” değerini taşıyan kardiz adlı karakter dizisi ile “armut” karakter dizisini kardiz2 adlı başka bir değişkene atamış olduk. Ancak tabii ki özgün karakter dizisi yerli yerinde duruyor:
>>> print kardiz
elma
Dediğimiz gibi, değişiklikleri özgün karakter dizisinin üzerine de yazabiliriz:
>>> kardiz = kardiz + "armut"
>>> print kardiz
elmaarmut
Burada kardiz adlı karakter dizisini silip, yine “kardiz” adını taşıyan başka bir karakter dizisi oluşturmuş olduk. Yukarıdaki örneği şu şekilde kısaltabileceğimizi biliyorsunuz:
>>> kardiz += "armut"
>>> print kardiz
elmaarmut
Gösterdiğimiz bu özelliği daha karmaşık bir örnek içinde kullanalım. Diyelim ki elinizde şöyle bir metin var:
saüipö 1990 ajnjöfcö çv acöc çyaym çkş
üpsnvnvm ücşcğjöfcö hgnkuükşkngö mjzşcm zg fköcokm çkş fknfkş.
trb fkbkokökö tcfg pnoctj, mpnca rışgöknogtk zg sşphşco
hgnkuükşog tyşgdkök ijbncöfjşoctj kng ücöjöcö çv fkn
wköfpwt, höv/nkövx zg ocdpt x hkçk sgm epm ğcşmnj kungüko
tktügok ybgşköfg ecnjucçknogmügfkş. fpncajtjanc ügm çkş
sncüğpşofc hgnkuükşfkıkökb çkş saüipö vahvncoctj, ybgşköfg
ike çkş fgıkukmnkm acsocac hgşgm pnocfcö zgac myeym
fgıkukmnkmngşng çcumc sncüğpşoncşfc fc ecnjucçkngdgmükş.
Anlamsız harflerden oluşmuş gibi görünen bu metin, Türkçe bir metnin şifrelenmiş halidir. Burada hangi harfin hangi harfe karşılık geldiğini gösteren şöyle bir tablo da olsun elimizde:
ğ = f ı = ğ v = u g = e ş = r
a = y c = a b = z e = ç d = c
ç = b f = d i = h h = g k = i
j = ı m = k l = j o = m n = l
p = o s = p r = ö u = ş t = s
ö = n y = ü z = v ü = t
Bu tablo, şifrelenmiş metin içinde gördüğümüz her harfin alfabedeki karşılığını gösteriyor. Yani mesela şifrelenmiş metin içindeki “ğ” harfini “f” harfiyle değiştireceğiz.
Bu bilgileri kullanarak, yukarıdaki şifreli metni rahatlıkla çözebiliriz. Bunun için şöyle bir kod yazmamız yeterli olacaktır:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
sifreli_metin = """saüipö 1990 ajnjöfcö çv acöc çyaym çkş
üpsnvnvm ücşcğjöfcö hgnkuükşkngö mjzşcm zg fköcokm çkş fknfkş.
trb fkbkokökö tcfg pnoctj, mpnca rışgöknogtk zg sşphşco
hgnkuükşog tyşgdkök ijbncöfjşoctj kng ücöjöcö çv fkn
wköfpwt, höv/nkövx zg ocdpt x hkçk sgm epm ğcşmnj kungüko
tktügok ybgşköfg ecnjucçknogmügfkş. fpncajtjanc ügm çkş
sncüğpşofc hgnkuükşfkıkökb çkş saüipö vahvncoctj, ybgşköfg
ike çkş fgıkukmnkm acsocac hgşgm pnocfcö zgac myeym
fgıkukmnkmngşng çcumc sncüğpşoncşfc fc ecnjucçkngdgmükş."""
sozluk = {"a": "y", "b": "z", "c": "a",
"ç": "b", "d": "c", "e": "ç",
"f": "d", "g": "e", "ğ": "f",
"h": "g", "ı": "ğ", "i": "h",
"j": "ı", "k": "i", "l": "j",
"m": "k", "n": "l", "o": "m",
"ö": "n", "p": "o", "r": "ö",
"s": "p", "ş": "r", "t": "s",
"u": "ş", "ü": "t", "v": "u",
"y": "ü", "z": "v"}
sifresiz_metin = ""
for harf in sifreli_metin:
sifresiz_metin += sozluk.get(harf, harf)
print sifresiz_metin
Burada karakter dizilerini nasıl birleştirdiğimize dikkat edin. Aslında bu kodlarda şöyle bir şey yapmış olduk:
- Önce şifreli metnimizi bir karakter dizisi olarak tanımladık. Uzun bir metinle karşı karşıya olduğumuzdan, satır sonlarında bir sonraki satıra geçerken problem yaşamamak için karakter dizisini tanımlarken üç tırnak işaretlerinden yararlandık. Bildiğiniz gibi, birden fazla satıra yayılmış uzun karakter dizilerini tanımlamanın en kolay yolu üç tırnak kullanmaktır.
- Daha sonra hangi harfin hangi harfe karşılık geldiğini gösteren tablomuzu bir sözlük haline getiriyoruz.
- Ardından, şifreli metnin çözülmüş halini tutacak olan sifresiz_metin adlı karakter dizimizi tanımlıyoruz. Bir sonraki adımda her bir karakteri birbiriyle birleştirip bu boş karakter dizisi içine göndereceğiz.
- Şimdi de sifreli_metin adlı karakter dizisi içindeki her bir karakteri, sözlükteki karşılıklarına göre tek tek sifresiz_metin adlı karakter dizisine gönderiyoruz. Burada sözlüklerin get() adlı metodunu kullandığımıza dikkat edin. Eğer bu metodun nasıl kullanıldığına ilişkin şüpheleriniz varsa Sözlükler bölümündeki get() metoduna bakabilirsiniz.
- Son olarak da sifresiz_metin adlı karakter dizisini ekrana yazdırıyoruz.
Ayrıca bkz.
Benzer bir örnek: http://www.istihza.com/blog/this-modulu-icindeki-sifreli-metin.html/
Dediğimiz gibi, Python’da karakter dizilerini birleştirmek için elimizde çeşitli alternatifler var. Biz yukarıda “+” işlecini kullanarak karakter dizilerini nasıl birleştirebileceğimizi gördük. Karakter dizilerini ”,” işaretleriyle de birleştirebiliriz:
>>> a = "birinci karakter dizisi"
>>> b = "ikinci karakter dizisi"
>>> print a, b
birinci karakter dizisi ikinci karakter dizisi
Gördüğünüz gibi, karakter dizilerini ”,” işaretiyle birleştirdiğimizde Python karakter dizileri arasına otomatik olarak bir boşluk yerleştiriyor. Gelin isterseniz bununla ilgili olarak az çok işe yarar bir örnek verelim:
# -*- coding: cp1254 -*-
import os
print "Kullanıcı adı: ", os.environ["USERNAME"]
print "Bilgisayar adı: ", os.environ["COMPUTERNAME"]
print "Ev dizini: ", os.environ["HOMEPATH"]
print "İşlemci: ", os.environ["PROCESSOR_IDENTIFIER"]
print "İşlemci sayısı: ", os.environ["NUMBER_OF_PROCESSORS"]
print "İşletim sistemi:", os.environ["OS"]
Bu betik yardımıyla kullanıcının işletim sistemine ilişkin bazı bilgileri ekrana döktük. Burada os modülünün environ adlı niteliğinden yararlandığımıza dikkat edin. os.environ aslında bir sözlüktür. Dolayısıyla bu sözlük birtakım anahtar-değer çiftlerinden oluşur. Bu sözlükteki bütün anahtar-değer çiftlerini ekrana dökmek için şöyle bir şey yazabilirsiniz:
>>> for k, v in os.environ.items():
... print k, v
Bu komutların çıktısı, kullandığınız işletim sistemine göre bazı farklılıklar gösterebilir. Örneğin yukarıdaki betik Windows kurulu bir bilgisayar üzerinde yazılmıştır. Dolayısıyla bu betiğin çıktısı GNU/Linux işletim sistemlerinde farklı olacaktır.
Yukarıdaki iki örnekte de karakter dizilerini birleştirmek için ”,” işaretlerinden yararlandığımıza dikkat edin.
Karakter Dizilerini Dilimlemek¶
Bazı durumlarda, elimizdeki bir karakter dizisinin tamamına ihtiyacımız olmayabilir. Yazdığımız program açısından, elimizdeki karakter dizisinin sadece bir bölümünü kullanmak isteyebiliriz.
Elimizde şöyle bir karakter dizisi olduğunu varsayalım:
>>> url = "http://www.istihza.com"
Diyelim ki biz bu karakter dizisinin başındaki http:// kısmını atmak istiyoruz... İşte bunun için karakter dizilerinin “dilimleme” (slicing) özelliğinden faydalanabiliriz. Yukarıdaki örneği dilimlemeden önce dilerseniz bir iki temel örnek üzerinden dilimlemenin ne demek olduğunu anlamaya çalışalım:
>>> kardiz = "elma"
>>> print kardiz[0]
e
>>> print kardiz[1]
l
>>> print kardiz[-1]
a
Burada kardiz adlı karakter dizisinin öğelerine tek tek nasıl ulaşabildiğimizi görüyorsunuz. Böyle bir kullanımı listelerde ve demetlerde de görmüştük:
>>> lst = ["Python", "Perl", "Ruby", "PHP"]
>>> print lst[0]
Python
>>> print lst[-1]
PHP
Bu yöntemi kullanarak, karakter dizilerini dilim dilim bölebiliriz. Mesela:
>>> kardiz = "Python"
>>> print kardiz[0:4]
Pyth
>>> print kardiz[2:5]
tho
Gördüğünüz gibi, bu yöntemle karakter dizilerinin istediğimiz bir parçasını alabiliyoruz. Gelin bununla ilgili bazı denemeler yapalım:
>>> kardiz = "Kahramanmaraşlı Abdullah"
>>> print kardiz[0:5]
Kahra
>>> print kardiz[:5]
Kahra
Eğer ”:” işaretinden önceki değerimiz 0 ise, bu değeri yazmasak da olur. ”:” işaretinden önce herhangi bir değer belirtmezsek Python saymaya en baştan başlayacak, sanki oraya 0 yazmışsınız gibi davranacaktır. Yani ”:” işaretinden önceki öğenin varsayılan değeri 0’dır... Bir de şuna bakalım:
>>> print kardiz[3:]
ramanmaraşlı Abdullah
”:” işaretinden sonraki değeri yazmadığımızda ise karakter dizisinin sonuna kadar gidiliyor. Yukarıdaki komut şununla eşdeğerdir:
>>> print kardiz[3:len(kardiz)]
Şimdi isterseniz bu bölümün en başında verdiğimiz örneğe dönelim:
>>> url = "http://www.istihza.com"
Biraz önce gösterdiğimiz dilimleme yöntemini kullanarak bu karakter dizisinin en başındaki http:// kısmını atacağız:
>>> print url[7:]
www.istihza.com
Gördüğünüz gibi, baştaki http:// kısmını gayet şık bir şekilde attık... Bunu şöyle bir örnek içinde kullanabiliriz:
# -*- coding: utf-8 -*-
url_list = ["http://www.python.org",
"http://www.istihza.com",
"http://www.google.com",
"http://www.yahoo.com"]
for i in url_list:
print i[7:]
Karakter dizilerinin dilimlenme özelliğinden yararlanarak yapabilecekleriniz bunlarla sınırlı değildir elbette. Mesela:
>>> kardiz = "Python Programlama Dili"
>>> print kardiz[2:15:2]
to rgal
Burada, karakter dizisinin 2. karakterinden 15. karakterine kadar olan kısmı ikişer ikişer atlayarak ekrana yazdırdık. Aynı karakter dizisinin başından sonuna kadar üçer üçer atlayarak ilerlemek isteseydik şöyle bir şey yazabilirdik:
>>> print kardiz[::3]
Ph oaa l
Burada dilimleme özelliğinin varsayılan değerlerinden yararlandığımıza dikkat ediyoruz. Yani yukarıdaki kodu aslında şöyle de yazabilirdik:
>>> print kardiz[0:len(kardiz):3]
Ph oaa l
Eğer bir karakter dizisini ters çevirmek isterseniz yine bu dilimleme özelliğinden faydalanabilirsiniz:
>>> kardiz = "Python programlama dili öğrenmesi kolay bir dildir!"
>>> print kardiz[::-1]
!ridlid rib yalok isemnerğö ilid amalmargorp nohtyP
Karakter dizilerini dilimleyerek yapabilecekleriniz hakkında bir örnek daha vererek bu konuyu kapatalım:
# -*- coding: utf-8 -*-
url_list = ["http://www.python.org",
"http://www.istihza.com",
"http://www.google.com",
"http://www.yahoo.com"]
for i in url_list:
print "ftp" + i[10:]
Bu örnekte, url_list içinde bulunan adreslerin başındaki http://www kısmını atarak yerlerine ftp ifadesini getirdik...
Karakter Dizilerinin Metotları¶
Bu bölümde Python’daki karakter dizilerinin metotlarından söz edeceğiz. Şu halde isterseniz gelin Python’un bize hangi metotları sunduğunu topluca görelim:
>>> for i in dir(str):
... if "_" not in i:
... print i
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__',
'__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith',
'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit',
'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']
Gördüğünüz gibi, Python’da karakter dizilerinin bir hayli metodu varmış... Eğer bu listeleme biçimi gözünüze biraz karışık göründüyse, elbette çıktıyı istediğiniz gibi biçimlendirmek sizin elinizde.
Mesela önceki bilgilerinizi de kullanıp şöyle bir şey yaparak çıktıyı biraz daha okunaklı hale getirebilirsiniz:
>>> for i in dir(""):
... print i
Hatta kaç adet metot olduğunu da merak ediyorsanız şöyle bir yol izleyebilirsiniz. (“Elle tek tek sayarım,” diyenlere teessüflerimi iletiyorum...)
>>> print len(dir(""))
Şimdi sıra geldi bu metotları incelemeye...
Büyük-Küçük Harf Değiştirme¶
Python’da karakter dizilerinin büyük-küçük harf durumlarını değiştirmek için kullanabileceğimiz beş farklı metot var. Bu metotlar şöyle sıralanabilir:
- capitalize() metodu
- Karakter dizilerinin ilk harfini büyütür.
- title() metodu
- Karakter dizisi içinde geçen her bir kelimenin ilk harfini büyütür.
- upper() metodu
- Küçük harflerden oluşan bir karakter dizisi içindeki bütün harfleri büyütür.
- lower() metodu
- Büyük harflerden oluşan bir karakter dizisi içindeki bütün harfleri küçültür.
- swapcase() metodu
- Karakter dizisi içindeki büyük harfleri küçük, küçük harfleri büyük hale getirir.
Bu metotların tanımlarını verdiğimize göre, artık bunlarla ilgili örnekler yaparak bu metotların tam olarak ne işe yaradıklarını anlamaya çalışabiliriz.
İlk olarak capitalize() metoduyla başlayalım...
capitalize()¶
Dediğimiz gibi, capitalize() metodu bir karakter dizisinin ilk harfini büyütür. Örneğin:
>>> "adana".capitalize()
'Adana'
>>> kent = "adana"
>>> kent.capitalize()
'Adana'
Yalnız burada dikkat etmemiz gereken bir nokta var: Bu metot yardımıyla birden fazla kelime içeren karakter dizilerinin sadece ilk kelimesinin ilk harfini büyütebiliyoruz:
>>> a = "lütfen parolanızı giriniz"
>>> print a.capitalize()
Lütfen parolanızı giriniz
Bu metodu kullanarak bir liste içindeki bütün karakter dizilerinin ilk harfini büyütebilirsiniz:
>>> a = ["elma", "armut", "kebap", "salata"]
>>> for i in a:
... print i.capitalize()
...
Elma
Armut
Kebap
Salata
title()¶
capitalize() metoduna çok benzeyen bir başka metot ise title() adlı metottur. capitalize() metodu bir karakter dizisi içinde geçen yalnızca ilk kelimenin ilk harfini büyütüyordu. title() metodu ise bir karakter dizisi içindeki bütün kelimelerin ilk harflerini büyütüyor:
>>> a = u"cumhurbaşkanlığı senfoni orkestrası"
>>> print a.title()
Cumhurbaşkanlığı Senfoni Orkestrası
Burada dikkat ederseniz karakter dizisini tanımlarken karakter dizisinin en başına bir “u” harfi getirdik. Esasında biz bu harfi önceki derslerimizde de görmüştük. Bir-iki ders sonra bu harfin tam olarak ne işe yaradığını gayet net bir şekilde öğreneceğiz. Şimdilik biz sadece bunun karakter dizisi içindeki Türkçe harflerin düzgün çıktı vermesini sağladığını bilelim yeter. Dilerseniz karakter dizisini “u” harfi olmadan tanımlamayı deneyip sonucun ne olduğunu kendi gözlerinizle görebilirsiniz.
Sıra geldi upper() adlı metodu incelemeye...
upper()¶
Yukarıda yaptığımız tanımdan da anlaşılacağı gibi, bu metot yardımıyla tamamı küçük harflerden oluşan bir karakter dizisinin bütün harflerini büyütebiliyoruz. Hemen bir örnek verelim:
>>> "enflasyon".upper()
ENFLASYON
Gördüğünüz gibi, “enflasyon” kelimesinin bütün harflerini büyük harfe çevirdik.
upper() metodunun bir de tersi vardır: lower() metodu. lower() metodu büyük harflerden oluşan karakter dizilerini küçük harfli karakter dizilerine dönüştürüyor:
>>> a = "ARMUT"
>>> a.lower()
armut
swapcase()¶
Bu başlıkta inceleyeceğimiz son metodumuzun adı swapcase(). Bu metot bize, bir karakter dizisinin o anda sahip olduğu harflerin büyüklük ve küçüklük özellikleri arasında geçiş yapma imkanı sağlıyor. Yani, eğer o anda bir harf büyükse, bu metodu kullandığımızda o harf küçülüyor; eğer bu harf o anda küçükse, bu metot o harfi büyük harfe çeviriyor. Gördüğünüz gibi, bu metodun ne yaptığını, anlatarak açıklamak zor oluyor. O yüzden hemen birkaç örnek yapalım:
>>> a = "kebap"
>>> a.swapcase()
KEBAP
>>> b = "KEBAP"
>>> b.swapcase()
kebap
>>> c = "KeBaP"
>>> c.swapcase()
kEbAp
Büyük-Küçük Harf ve Boşluk Sorgulama¶
Yukarıda gösterdiğimiz şekilde karakter dizilerinin büyük-küçük harf durumlarını değiştirebiliyoruz. Python bize aynı zamanda karakter dizilerinin büyük-küçük harf durumlarını sorgulama imkanı da veriyor. Bu sorgulama işlemleri için yine birtakım metotlardan yararlanıyoruz. Bu metotları şöyle sıralayabiliriz:
- islower()
- Karakter dizisinin tamamen küçük harflerden oluşup oluşmadığını sorgular
- isupper()
- Karakter dizisinin tamamen büyük harflerden oluşup oluşmadığını sorgular
- istitle()
- Karakter dizisi içindeki kelimelerin ilk harflerinin büyük olup olmadığını sorgular
- isspace()
- Karakter dizisinin tamamen boşluk karakterlerinden oluşup oluşmadığını sorgular
İlk metodumuz olan islower() ile başlayalım...
islower()¶
Bir karakter dizisinin tamamen küçük harflerden oluşup oluşmadığını sorgulamak için islower() metodundan yararlanacağız. Mesela:
>>> kent = "istanbul"
>>> kent.islower()
True
Demek ki kent değişkeninin değeri olan karakter dizisi tamamen küçük harflerden oluşuyormuş.
Aşağıdaki örnekler ise False (yanlış) çıktısı verecektir:
>>> a = "İstanbul"
>>> a.islower()
False
>>> b = "ADANA"
>>> b.islower()
False
isupper()¶
Bir karakter dizisinin tamamen büyük harflerden oluşup oluşmadığını denetlemek için ise isupper() adlı başka bir metottan faydalanıyoruz:
>>> a = "ADANA"
>>> a.isupper()
True
>>> "istanbul".isupper()
False
istitle()¶
Hatırlarsanız daha önce öğrendiğimiz metotlar arasında title() adlı bir metot vardı. Bu metot yardımıyla tamamı küçük harflerden oluşan bir karakter dizisinin ilk harflerini büyütebiliyorduk. İşte şimdi öğreneceğimiz istitle() metodu da bir karakter dizisinin ilk harflerinin büyük olup olmadığını sorgulamamızı sağlayacak:
>>> a = "Karakter Dizisi"
>>> a.istitle()
True
>>> b = "karakter dizisi"
>>> b.istitle()
False
Gördüğünüz gibi, eğer karakter dizisinin ilk harfleri büyükse bu metot True çıktısı; aksi halde False çıktısı veriyor.
isspace()¶
Son olarak isspace() adlı bir metottan söz edeceğiz. Bu metot ile, bir karakter dizisinin tamamen boşluk karakterlerinden oluşup oluşmadığını kontrol ediyoruz. Eğer bir karakter dizisi tamamen boşluk karakterinden oluşuyorsa, bu metot True çıktısı verecektir. Aksi halde, alacağımız çıktı False olacaktır:
>>> a = " "
>>> a.isspace()
True
>>> a = "selam!"
>>> a.isspace()
False
>>> a = ""
>>> a.isspace()
False
Son örnekten de gördüğümüz gibi, bu metodun True çıktısı verebilmesi için karakter dizisi içinde en az bir adet boşluk karakteri olması gerekiyor.
Metotlarda Türkçe Karakter Sorunu¶
Yukarıda anlattığımız beş metodu kullanırken bir şey dikkatinizi çekmiş olmalı. Karakter dizilerinin upper(), lower(), title(), capitalize() ve swapcase() adlı metotları, içinde Türkçe karakterler geçen karakter dizilerini dönüştürmede sorun çıkarabiliyor. Mesela şu örneklere bir bakalım:
>>> a = "şekerli çay"
>>> print a.capitalize()
şekerli çay
Gördüğünüz gibi, “şekerli çay” karakter dizisinin ilk harfi olan “ş”de herhangi bir değişiklik olmadı. Halbuki capitalize() metodunun bu harfi büyütmesi gerekiyordu. Bu problemi şu şekilde aşabiliriz:
>>> a = u"şekerli çay"
>>> print a.capitalize()
Şekerli çay
Burada “şekerli çay” karakter dizisini “unicode” olarak tanımladık. Böylece capitalize() metodu bu karakter dizisinin ilk harfini doğru bir şekilde büyütebildi.
Aynı sorun öteki metotlar için de geçerlidir:
>>> a = "şekerli çay"
>>> print a.upper() #"ŞEKERLİ ÇAY" vermeli.
şEKERLI çAY
>>> print a.title() #"Şekerli Çay" vermeli.
şEkerli çAy
>>> a = "şEkErLi çAy"
>>> print a.swapcase() #"ŞeKeRlİ ÇaY" vermeli.
şeKeRlI çaY
>>> a = "ŞEKERLİ ÇAY"
>>> print a.lower() #"şekerli çay" vermeli.
Şekerlİ Çay
Yukarıdaki sorunların çoğunu, ilgili karakter dizisini unicode olarak tanımlayarak giderebiliriz:
>>> a = u"şekerli çay"
>>> print a.title()
Şekerli Çay
Ancak karakter dizisini unicode olarak tanımlamanın dahi işe yaramayacağı bir durum da vardır. Türkçe’deki “i” harfi hiçbir dönüşümde “İ” sonucunu vermez... Örneğin:
>>> a = u"şekerli çay"
>>> print a.upper()
ŞEKERLI ÇAY
>>> a = "şEkErLi çAy"
>>> print a.swapcase()
ŞeKeRlI ÇaY
Gördüğünüz gibi, “i” harfinin büyük hali yanlış bir şekilde “I” oluyor. Aynı biçimde “I” harfi de küçültüldüğünde “ı” harfini değil, “i” harfini verecektir:
>>> a = u"ISLIK"
>>> print a.lower()
islik
Bu sorunları çözebilmek için, kendi metotlarınızı icat etmeyi deneyebilirsiniz. Örneğin Türkçe karakterleri düzgün bir şekilde büyütebilen bir tr_upper() fonksiyonu tanımlayabilirsiniz:
# -*- coding: utf-8 -*-
lst = {u"i": u"İ",
u"ı": u"I"}
def tr_upper(kardiz):
for i in lst:
if i in kardiz:
return kardiz.replace(i, lst[i]).upper()
return kardiz.upper()
Buradaki replace() metodunu biraz sonra işleyeceğiz...
Gelin isterseniz bu Türkçe sorunu ile ilgili bir örnek daha gösterelim:
>>> c = "Gün Bugündür"
>>> c.istitle()
False
Halbuki sonucun True olması gerekiyordu, değil mi? Peki sizce neden böyle oldu? Evet, tahmin ettiğiniz gibi, karakter dizisinin içinde Türkçe’ye özgü harfler olduğu için metodumuz yanlış sonuç verdi. Şimdi bunu düzeltmeyi öğreneceğiz. Ama önce isterseniz Türkçe karakterlerin bazen nasıl sonuçlar doğurabileceğine bir örnek verelim:
>>> d = "gün bugündür"
>>> print d.title()
GüN BugüNdüR
Gördüğünüz gibi Türkçe karakterler, title metodunun tamamen kontrolden çıkmasına, kısa devre yapmasına yol açtı!... Normalde title() metodunun ne yapması gerektiğini biliyoruz:
>>> e = "armut bir meyvedir"
>>> e.title()
'Armut Bir Meyvedir'
Yukarıda gördüğümüz, Türkçe karakterler barındıran örnekte ise title() metodu karakter dizisi içindeki kimi harfleri büyüttü, kimi harfleri ise küçük bıraktı!
Bu durumu nasıl düzelteceğimizi biliyorsunuz:
>>> c = u"Gün Bugündür"
>>> c.istitle()
True
Burada karakter dizisini unicode olarak tanımladığımıza dikkat edin. Bu defa metotların sorunsuz işlediğini göreceksiniz.
Sağa-Sola Yaslama İşlemleri¶
Python’da karakter dizilerini sağa-sola yaslama işlemleri için kullanabileceğimiz üç farklı metot bulunur. Bunları şöyle sıralayabiliriz:
- center() metodu
- Karakter dizilerinin sağında ve solunda, programcının belirlediği sayıda boşluk bırakarak karakter dizisini iki yana yaslar.
- ljust() metodu
- Karakter dizilerinin sağında boşluk bırakarak, karakter dizisinin sola yaslanmasını sağlar.
- rjust() metodu
- Karakter dizilerinin solunda boşluk bırakarak, karakter dizisinin sağa yaslanmasını sağlar.
Gelelim bu metotların tam olarak ne işe yaradığını öğrenmeye... Öncelikle center() metodundan başlayalım.
center()¶
Tanımında da söylediğimiz gibi, center() metodu bir karakter dizisini iki yana yaslamak için kullanılır. Gelin isterseniz buna küçük bir örnek verelim:
>>> "a".center(15)
' a '
Gördüğünüz gibi, bu metodun parantezi içine yazdığımız sayı karakter dizisinin sağında ve solunda toplam ne kadar boşluk bırakılacağını gösteriyor. Yalnız burada önemli bir ayrıntıya dikkatinizi çekmek isterim. Parantez içinde gösterilen 15 karakterlik boşluğa karakter dizisinin kendisi de dahildir. Peki bu ne anlama geliyor? Durumu hemen bir örnekle açıklamaya çalışalım:
>>> kardiz = "istanbul"
>>> kardiz.center(5)
'istanbul'
Gördüğünüz gibi, karakter dizisinin sağında ve solunda herhangi bir boşluk oluşmadı. Bunun nedeni, parantez içinde belirttiğimiz 5 sayısının “istanbul” karakter dizisi içindeki karakter sayısından az olmasıdır. Yani “istanbul” karakter dizisi bu 5 karakterlik boşluğun tamamını zaten kendisi dolduruyor. Dolayısıyla karakter dizisinin sağında ve solunda boşluk olabilmesi için en az, karakter dizisinin uzunluğunun bir fazlasını vermemiz gerekiyor. Yani:
>>> kardiz.center(len("istanbul") + 1)
' istanbul'
Buna göre, “istanbul” karakter dizisi içinde 8 karakter bulunduğu için bizim en az 9 sayısını kullanmamız gerekiyor:
>>> kardiz.center(9)
' istanbul'
center() metodu bize, boşluk yerine kendi belirlediğimiz bir karakteri yerleştirme imkanı da verir:
>>> "istanbul".center(15, "#")
'####istanbul###'
Bu çıktı aslında center() metodunun nasıl çalıştığını çok daha net bir şekilde ortaya koyuyor. Dikkat ederseniz çıktıda toplam 15 karakter var. Bunlardan dört tanesi bizim belirlediğimiz “#” karakteri, 8 tanesi “istanbul” karakter dizisini oluşturan karakterler, 3 tanesi ise yine bizim belirlediğimiz “#” karakteri...
Gördüğünüz gibi, parantez içinde belirttiğimiz sayı bırakılacak boşluktan ziyade, bir karakter dizisinin ne kadar yer kaplayacağını gösteriyor. Yani mesela yukarıdaki örneği göz önüne alırsak, asıl karakter dizisi (“istanbul”) + 7 adet “#” işareti = 15 adet karakter dizisinin yerleştirildiğini görüyoruz. Eğer karakter dizimiz, 15 harften oluşsaydı, parantez içinde verdiğimiz 15 sayısı hiç bir işe yaramayacaktı. Böyle bir durumda, “#” işaretini çıktıda gösterebilmek için parantez içinde en az 16 sayısını kullanmamız gerekirdi.
Gelelim ljust() metoduna...
ljust()¶
Tanımında da belirttiğimiz gibi bu metot, karakter dizilerinin sağında boşluk bırakarak, karakter dizisinin sola yaslanmasını sağlar:
>>> "istanbul".ljust(15)
'istanbul '
Tıpkı center() metodunda olduğu gibi, bunun parametrelerini de istediğimiz gibi düzenleyebiliriz:
>>> "istanbul".ljust(15, "#")
'istanbul#######'
Son olarak rjust() metodunu inceleyelim.
rjust()¶
Bu metot ljust()‘ın tersidir. Yani karakter dizilerini sağa yaslar:
>>> "istanbul".rjust(15, "#")
'#######istanbul'
Sağa-sola yaslama işlemleri için kullanılan bu metotlar içinde özellikle ljust() ve rjust() epey işinize yarayacak. Mesela bu metotları kullanarak “tablovari” görünümler elde edebilirsiniz:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
distro = ["Ubuntu", "Debian", "SuSe", "Pardus",
"Fedora", "PCLinuxOS", "Arch", "Gentoo",
"Hadron", "Truva", "Gelecek", "Mandriva",
"Sabayon", "Mint", "Slackware", "Mepis",
"CentOS", "Puppy", "GnewSense", "Ututo",
"Red Hat", "Knoppix", "BackTrack", "Karoshi",
"Kongoni", "DreamLinux", "Yoper", "Slax"]
for k, v in enumerate(distro):
if k % 4 == 0:
print
print "%s"%(v.ljust(15)),
Bu kodları çalıştırdığımızda şöyle bir çıktı elde ederiz:
Ubuntu Debian SuSe Pardus
Fedora PCLinuxOS Arch Gentoo
Hadron Truva Gelecek Mandriva
Sabayon Mint Slackware Mepis
CentOS Puppy GnewSense Ututo
Red Hat Knoppix BackTrack Karoshi
Kongoni DreamLinux Yoper Slax
Son satırdaki ljust() metodu yerine rjust() metodunu kullanırsak aynı kodlar şöyle bir çıktı verir:
Ubuntu Debian SuSe Pardus
Fedora PCLinuxOS Arch Gentoo
Hadron Truva Gelecek Mandriva
Sabayon Mint Slackware Mepis
CentOS Puppy GnewSense Ututo
Red Hat Knoppix BackTrack Karoshi
Kongoni DreamLinux Yoper Slax
Gördüğünüz gibi, bu defa tablo öğeleri sağa yaslandı. Bu öğeleri ekrana ortalamak için ise center() metodunu kullanabileceğimizi biliyorsunuz. Mesela son satırı şöyle yazalım:
print "%s"%(v.center(15, "~")),
Bu şekilde şöyle bir çıktı elde ederiz:
~~~~~Ubuntu~~~~ ~~~~~Debian~~~~ ~~~~~~SuSe~~~~~ ~~~~~Pardus~~~~
~~~~~Fedora~~~~ ~~~PCLinuxOS~~~ ~~~~~~Arch~~~~~ ~~~~~Gentoo~~~~
~~~~~Hadron~~~~ ~~~~~Truva~~~~~ ~~~~Gelecek~~~~ ~~~~Mandriva~~~
~~~~Sabayon~~~~ ~~~~~~Mint~~~~~ ~~~Slackware~~~ ~~~~~Mepis~~~~~
~~~~~CentOS~~~~ ~~~~~Puppy~~~~~ ~~~GnewSense~~~ ~~~~~Ututo~~~~~
~~~~Red Hat~~~~ ~~~~Knoppix~~~~ ~~~BackTrack~~~ ~~~~Karoshi~~~~
~~~~Kongoni~~~~ ~~~DreamLinux~~ ~~~~~Yoper~~~~~ ~~~~~~Slax~~~~~
Sıfırla Doldurma¶
zfill()¶
Yukarıda bahsettiğimiz ljust(), rjust() gibi metotlar yardımıyla karakter dizilerinin sağını-solunu istediğimiz karakterlerle doldurabiliyorduk. Karakter dizilerinin metotları arasında yer alan zfill() adlı bir metot yardımıyla da bir karakter dizisinin soluna istediğimiz sayıda “0” yerleştirebiliriz:
>>> a = "8"
>>> a.zfill(4)
0008
zfill() metodunun kullanımıyla ilgili şöyle bir örnek verebiliriz:
import time
while True:
for i in range(21):
time.sleep(1)
print str(i).zfill(2)
while i > 20:
continue
Karakter Değiştirme¶
replace()¶
Python’daki karakter dizisi metotları içinde belki de en çok işimize yarayacak metotlardan birisi de bu replace() metodudur. “replace” kelimesi İngilizce’de “değiştirmek, yerine koymak” gibi anlamlara gelir. Dolayısıyla anlamından da anlaşılacağı gibi bu metot yardımıyla bir karakter dizisi içindeki karakterleri başka karakterlerle değiştiriyoruz. Metot şu formül üzerine işler:
karakter_dizisi.replace("eski_karakter", "yeni_karakter")
Hemen bir örnek vererek durumu somutlaştıralım:
>>> karakter = "Kahramanmaraşlı Abdullah"
>>> print karakter.replace("a", "o")
Kohromonmoroşlı Abdulloh
Gördüğünüz gibi, replace() metodu yardımıyla karakter dizisi içindeki bütün “a” harflerini kaldırıp yerlerine “o” harfini koyduk. Burada normalde print deyimini kullanmasak da olur, ama karakter dizisi içinde Türkçe’ye özgü harfler olduğu için, eğer :keyword`print` deyimini kullanmazsak çıktıda bu harfler bozuk görünecektir.
Bu metodu, isterseniz bir karakteri silmek için de kullanabilirsiniz. O zaman şöyle bir şey yapmamız gerekir:
>>> karakter = "Adanalı istihza"
>>> karakter_dgs = karakter.replace("a", "")
>>> print karakter_dgs
Adnlı istihz
Burada bir karakteri silmek için içi boş bir karakter dizisi oluşturduğumuza dikkat edin.
replace() metodunun, yukarıdaki formülde belirtmediğimiz üçüncü bir parametresi daha vardır. Dikkat ettiyseniz, yukarıdaki kod örneklerinde replace metodu karakter dizisi içindeki bir karakteri, dizi içinde geçtiği her yerde değiştiriyordu. Yani örneğin a.replace("b", "c") dediğimizde, a değişkeninin sakladığı karakter dizisi içinde ne kadar “b” harfi varsa bunların hepsi “c”ye dönüşüyor. Bahsettiğimiz üçüncü parametre yardımıyla, karakter dizisi içinde geçen harflerin kaç tanesinin değiştirileceğini belirleyebiliyoruz:
>>> karakter = "Adanalı istihza"
>>> karakter_dgs = karakter.replace("a", "", 2)
>>> print karakter_dgs
Adnlı istihza
Burada, “Adanalı istihza” karakter dizisi içinde geçen “a” harflerinden 2 tanesini siliyoruz.
“a” harfi ile “A” harfinin Python’un gözünde birbirlerinden farklı iki karakterler olduğunu unutmayın...
Karakter Dizilerinin Başlangıç ve Bitiş Değerlerini Sorgulama¶
Python’da karakter dizilerinin en başındaki ve en sonundaki karakterler üzerinde işlem yapabilmemizi sağlayan iki farklı metot bulunur. Bunlardan birincisi startswith() metodudur.
startswith()¶
Bu metot yardımıyla bir karakter dizisinin belirli bir harf veya karakterle başlayıp başlamadığını denetleyebiliyoruz. Örneğin:
>>> a = "elma"
>>> a.startswith("e")
True
>>> b = "armut"
>>> a.startswith("c")
False
Görüldüğü gibi eğer bir karakter dizisi parantez içinde belirtilen harf veya karakterle başlıyorsa, yani bir karakter dizisinin ilk harfi veya karakteri parantez içinde belirtilen harf veya karakterse “doğru” anlamına gelen True çıktısını; aksi halde ise “yanlış” anlamına gelen False çıktısını elde ediyoruz.
Bu metot sayesinde karakter dizilerini ilk harflerine göre sorgulayıp sonuca göre istediğimiz işlemleri yaptırabiliyoruz:
>>> liste = ["elma", "erik", "ev", "elbise", "karpuz", "armut", "kebap"]
>>> for i in liste:
... if i.startswith("e"):
... i.replace("e", "i")
...
'ilma'
'irik'
'iv'
'ilbisi'
Sizin bu metodu kullanarak daha faydalı kodlar yazacağınıza inanıyorum...
endswith()¶
endswith(), yukarıda anlattığımız startswith() metodunun yaptığı işin tam tersini yapıyor. Hatırlarsanız startswith() metodu ile, bir karakter dizisinin hangi harfle başladığını denetliyorduk. İşte bu endswith() metodu ile ise karakter dizisinin hangi harfle bittiğini denetleyeceğiz. Kullanımı startswith() metoduna çok benzer:
>>> a = "elma"
>>> a.endswith("a")
True
>>> b = "armut"
>>> a.endswith("a")
False
Bu metot yardımıyla, cümle sonlarında bulunan istemediğiniz karakterleri ayıklayabilirsiniz:
>>> kd1 = "ekmek elden su gölden!"
>>> kd2 = "sakla samanı gelir zamanı!"
>>> kd3 = "karga karga gak dedi..."
>>> kd4 = "Vay vicdansızlar..."
>>> for i in kd1, kd2, kd3, kd4:
... if i.endswith("!"):
... print i.replace("!", "")
...
ekmek elden su gölden
sakla samanı gelir zamanı
Karakter Dizilerini Sayma¶
count()¶
count() metodu bize bir karakter dizisi içinde bir karakterden kaç adet bulunduğunu denetleme imkanı verecek. Lafı uzatmadan bir örnek verelim:
>>> besiktas = "Sinan Paşa Pasajı"
>>> besiktas.count("a")
5
Demek ki “Sinan Paşa Pasajı” karakter dizisi içinde 5 adet “a” harfi varmış...
Şimdi bu metodun nerelerde kullanılabileceğine ilişkin bir örnek verelim:
# -*-coding: utf-8 -*-
while True:
#replace metodu ile karakter dizisi içindeki
#boşlukları siliyoruz.
soru = raw_input("Bir karakter dizisi giriniz: ").replace(" ", "")
#Kümeleri kullanarak, karakter dizisi içindeki
#çift öğeleri teke indiriyoruz
ortak = set(soru)
#ortak kümesi içindeki öğeleri karakter dizisi
#içinde kaçar adet geçtiğini buluyoruz.
for i in ortak:
print "%s harfinden = => %s tane" %(i, soru.count(i))
Yukarıdaki çalışmada kullanıcıdan herhangi bir karakter dizisi girmesini istiyoruz. Kodlarımız bize, kullanıcının girdiği karakter dizisi içinde her bir harften kaç tane olduğunu söylüyor.
Karakter Dizilerinin Niteliğini Sorgulama¶
Karakterleri üçe ayırarak inceleyebiliriz:
- alfabetik karakterler
- nümerik karakterler
- alfanümerik karakterler
Alfabetik karakterler, adından da az çok anlaşılacağı gibi, alfabedeki harflerin ta kendisidir. Mesela “a”, “b”, “e”, “j”, vb...
Sayılar ve “_?=*” gibi simgeler alfabetik değildir.
isalpha()¶
Bir karakterin alfabetik olup olmadığını anlamak için Python’da isalpha() adlı bir metottan yararlanabiliriz:
>>> "a".isalpha()
True
Demek ki “a”, alfabetik bir karakter dizisi imiş. Bir de şuna bakalım:
>>> "1".isalpha()
False
Demek ki 1 alfabetik bir karakter değilmiş.
Şöyle bir örnek vererek durumu biraz daha netleştirelim:
>>> for i in "abc234_?=*jkl":
... if i.isalpha():
... print "%s alfabetik bir karakter dizisidir"%i
... else:
... print "%s alfabetik bir karakter dizisi değildir"%i
...
a alfabetik bir karakter dizisidir.
b alfabetik bir karakter dizisidir.
c alfabetik bir karakter dizisidir.
2 alfabetik bir karakter dizisi değildir.
3 alfabetik bir karakter dizisi değildir.
4 alfabetik bir karakter dizisi değildir.
_ alfabetik bir karakter dizisi değildir.
? alfabetik bir karakter dizisi değildir.
= alfabetik bir karakter dizisi değildir.
* alfabetik bir karakter dizisi değildir.
j alfabetik bir karakter dizisidir.
k alfabetik bir karakter dizisidir.
l alfabetik bir karakter dizisidir.
Ancak burada dikkat edilmesi gereken bir nokta var. Mesela şu örneğe bir bakalım:
>>> "ğ".isalpha()
False
Gördüğünüz gibi, isalpha() metodu Türkçe karakterleri doğru değerlendiremiyor. Bu sorunun üstesinden gelmek için Türkçe karakter dizilerini unicode olarak tanımlamanız gerekir:
>>> u"ğ".isalpha()
True
Sadece tek bir karakterin değil, birden fazla karakterden oluşan dizilerin alfabetik olup olmadığını da denetleyebiliriz. Örneğin:
>>> "istihza".isalpha()
True
Burada “istihza” karakter dizisi tamamen alfabetik karakterlerden oluştuğu için, “istihza kelimesi alfabetiktir,” diyoruz…
Bir de şuna bakalım:
>>> "istihza.com".isalpha()
False
“istihza.com” karakter dizisi içinde alfabetik olmayan bir karakter bulunduğu için (”.” karakteri), bu karakter dizisi alfabetik değildir. Dolayısıyla bir karakter dizisinin alfabetik olabilmesi için, o karakter dizisini oluşturan bütün karakterlerin alfabetik olması gerekir. Tek bir alfabetik olmayan karakter dizisi dahi işi bozar.
Bu arada, içinde Türkçe karakterler geçen bir karakter dizisinin alfabetik olup olmadığını denetlerken bu karakter dizisini unicode olarak tanımlamayı unutmuyoruz:
>>> "ışık".isalpha()
False
Doğrusu şöyle olacak:
>>> u"ışık".isalpha()
True
Gelelim “nümerik” karakterlere...
isdigit()¶
Nümerik karakterler alfabetik karakterlerin tersidir. Buna göre, sayıları temsil eden karakterlere nümerik adı verilir. Örneğin 1, 2, 5, 10, 20 sayıları nümerik karakterlerdir.
Bir karakterin nümerik olup olmadığını isdigit() metodunu kullanarak denetleyebiliriz:
>>> "1".isdigit
True
Ama:
>>> "a".isdigit()
False
Alfabetik karakter dizilerindeki “ya hep ya hiç” kuralı nümerik karakter dizileri için de geçerlidir. Yani bir karakter dizisinin nümerik olabilmesi için, o karakter dizisini oluşturan bütün karakterlerin nümerik olması gerekir. Tek bir nümerik olmayan karakter dahi, o karakter dizisinin nümerik olmamasına yol açacaktır…
Sıra geldi “alfanümerik” karakterlere...
isalnum()¶
Alfanümerik karakterler, yukarıda anlattığımız alfabetik ve nümerik karakterlerinin birleşimidir. Yani içinde hem alfabetik hem de nümerik karakterler barındıran dizilere alfanümerik karakter dizileri adı verilir. Tabii sadece alfabetik ve sadece nümerik karakterler barındıran diziler de aynı zamanda birer alfanümerik karakter dizisidir…
Tek bir karakter için konuşmak gerekirse, alfabetik veya nümerik olan karakterlere alfanümerik adı verilir.
Bir karakterin alfanümerik olup olmadığını Python’daki isalnum() adlı metot yardımıyla denetleyebiliriz.
Dilerseniz bu açıklamaları birkaç örnekle taçlandıralım:
>>> "a".isalnum()
True
Demek ki “a”, alfanümerik bir karaktermiş.
>>> "1".isalnum()
True
Demek ki 1 de alfanümerik bir karaktermiş…
Buradan şu sonuçları çıkarabiliriz:
- Bütün alfabetik karakterler aynı zamanda birer alfanümerik karakterdir.
- Bütün nümerik karakterler de aynı zamanda birer alfanümerik karakterdir.
- Bütün alfanümerik karakterler aynı zamanda birer alfabetik karakter OLMAYABİLİR.
- Bütün alfanümerik karakterler aynı zamanda birer nümerik karakter de OLMAYABİLİR.
Birden fazla karakterden oluşan dizilerin durumuna da bakalım isterseniz:
>>> "abc124".isalnum()
True
>>> "istihza.com".isalnum()
False
Gördüğünüz gibi, “istihza.com” karakter dizisi içindeki ”.” karakterinden ötürü karakter dizimiz alfanümerik olma özelliği taşıyamıyor. Bir karakter dizisinin alfanümerik olabilmesi için, barındırdığı bütün karakterlerin alfanümerik olması gerekir…
Sekme Boşluklarını Genişletme¶
expandtabs()¶
expandtabs() adlı bir metot yardımıyla karakter dizileri içindeki sekme boşluklarını genişletebiliyoruz: Örneğin:
>>> a = "elma\tbir\tmeyvedir"
>>> print a.expandtabs(10)
elma bir meyvedir
Karakter Konumu Bulma¶
Python’da bir karakterin karakter dizisi içinde hangi konumda yer aldığını bulabilmek için dört farklı metottan yararlanıyoruz. Bunlar find(), rfind(), index() ve rindex() metotlarıdır.
Öncelikle find() metodundan başlayalım.
find()¶
Bu metot, bir karakterin, karakter dizisi içinde hangi konumda yer aldığını söylüyor bize:
>>> a = "armut"
>>> a.find("a")
0
find() metodu karakter dizilerini soldan sağa doğru okur. Dolayısıyla eğer aradığımız karakter birden fazla sayıda bulunuyorsa, çıktıda yalnızca en soldaki karakter görünecektir:
>>> b = "adana"
>>> a.find("a")
0
Gördüğünüz gibi, find() metodu yalnızca ilk “a” harfini gösterdi.
Eğer aradığımız karakter, o karakter dizisi içinde bulunmuyorsa, çıktıda “-1” sonucu görünecektir:
>>> c = "mersin"
>>> c.find("t")
-1
find() metodu bize aynı zamanda bir karakter dizisinin belli noktalarında arama yapma imkanı da sunar. Bunun için şöyle bir sözdizimini kullanabiliriz:
>>> "karakter_dizisi".find("aranacak_karakter",başlangıç_noktası,bitiş_noktası)
Bir örnek verelim:
>>> a = "adana"
Burada normal bir şekilde “a” harfini arayalım:
>>> a.find("a")
0
Doğal olarak find() metodu karakter dizisi içinde ilk bulduğu “a” harfinin konumunu söyleyecektir. Bizim örneğimizde “a” harfi kelimenin başında geçtiği için çıktıda “0” ifadesini görüyoruz. Demek ki bu karakter dizisi içinedeki ilk “a” harfi “0’ıncı” konumdaymış.
İstersek şöyle bir arama yöntemi de kullanabiliriz:
>>> a.find("a", 1, 3)
Bu arama yöntemi şu sonucu verecektir:
2
Bu yöntemle, “a” harfini, karakter dizisinin 1 ve 3. konumlarında arıyoruz. Bu biçimin işleyişi, daha önceki derslerimizde gördüğümüz dilimleme işlemine benzer:
>>> a[1:3]
"da"
Peki bir karakter dizisi içinde geçen herhangi bir karakterin, o karakter dizisi içinde geçtiği bütün konumları bulmanın bir yolu var mı? Elbette var. Bunun için şöyle bir şey yazabilirsiniz:
# -*- coding: utf-8 -*-
def nerede(kardiz, harf):
lst = []
for i in range(len(kardiz)):
lst.append(kardiz.find(harf, i))
final = set(lst)
for o in final:
if int(o) > -1:
print o,
Bu fonksiyonu şöyle kullanıyoruz:
nerede(u"kahramanmaraş", "a")
Böylece “kahramanmaraş” karakter dizisi içindeki “a” harflerinin hangi konumlarda yer aldığını bulmuş olduk... Aynı şekilde “izmir” karakter dizisi içindeki “i” harflerinin konumunu sorgulayalım:
nerede(u"izmir", "i")
Bununla ilgili kendi kendinize bazı denemeler yaparak, işleyişi tam anlamıyla kavrayabilirsiniz.
rfind()¶
Python’da karakter dizisi içindeki karakterlerin konumunu bulmak için kullanabileceğimiz ikinci fonksiyonumuz rfind() fonksiyonudur. Bu metot yukarıda anlattığımız find() metodu ile aynı işi yapar. Tek farklı karakter dizilerini sağdan sola doğru okumasıdır.
find() metodu karakter dizilerini soldan sağa doğru okur. Mesela:
>>> a = "adana"
>>> a.find("a")
0
rfind() metodu ise karakter dizilerini sağdan sola doğru okur. Mesela:
>>> a.rfind("a")
4
Gördüğünüz gibi, rfind() metodu karakter dizisini sağdan sola doğru okuduğu için öncelikle en sondaki “a” harfini döndürdü.
index()¶
Konum bulma işlemleri için kullanabileceğimiz üçüncü metodumuz olan index() metodu da yukarıda anlattığımız find() metoduna çok benzer. İki metot da aynı işi yapar:
>>> a = "istanbul"
>>> a.index("t")
2
Bu metot da bize, tıpkı find() metodunda olduğu gibi, konuma göre arama olanağı sunar:
>>> b = "kahramanmaraş"
>>> b.index("a", 8, 10)
9
Demek ki, b değişkeninin tuttuğu karakter dizisinin 8 ve 10 numaralı konumları arasında “a” harfi 9. sırada yer alıyormuş....
Peki bu index() metodunun find() metodundan farkı nedir?
Hatırlarsanız find() metodu aradığımız karakteri bulamadığı zaman “-1” sonucunu veriyordu. index() metodu ise aranan karakteri bulamadığı zaman bir hata mesajı gösterir bize. Örneğin:
>>> c = "istanbul"
>>> c.index("m")
Bu kodlar şu çıktıyı verir:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
rindex()¶
Konum bulma işlemlerinde kullanacağımız son metodumuz ise rindex() metodudur. Bu metot, index() metodu ile aynıdır. Farkları, rindex() metodunun karakter dizisini sağdan sola doğru; index() metodunun ise soldan sağa doğru okumasıdır:
>>> c = "adana"
>>> c.index("a")
0
>>> c.rindex("a")
4
join() metodu¶
join() metodu, karakter dizisi metotları arasında bulunan en önemli ve en yaygın kullanılan metotlardan biridir. O yüzden bu metodu hakkıyla öğrenmenizde büyük yarar var...
Bu metodu açıklamak biraz zor ve kafa karıştırıcı olabilir. O yüzden açıklama yerine doğrudan bir örnekle, bu metodun ne işe yaradığını göstermeye çalışalım.
Şöyle bir karakter dizimiz olsun:
>>> a = "Linux"
Şimdi şöyle bir işlem yapalım:
>>> ".".join(a)
Elde edeceğimiz çıktı şöyle olur:
L.i.n.u.x
Sanırım burada join() metodunun ne iş yaptığı anlaşılıyor. “Linux” karakter dizisi içindeki bütün karakterlerin arasına birer tane ”.” (nokta) koydu. Tabii ki, nokta yerine başka karakterler de kullanabiliriz:
>>> "*".join(a)
L*i*n*u*x
Dikkat ederseniz join() metodunun sözdizimi öteki metotlarınkinden biraz farklı. Bu metotta parantez içine doğrudan değişkenin kendisi yazdık. Yani a.join("*") gibi bir şey yazmıyoruz.
Bu metot yardımıyla ayrıca listeleri de karakter dizisine çevirebiliriz. Mesela elimizde şöyle bir liste olsun:
>>> a = ["python", "php", "perl", "C++", "Java"]
Bu listenin öğelerini tek bir karakter dizisine dönüştürmek için şu kodu kullanıyoruz:
>>> "; ".join(a)
'python; php; perl; C++; Java'
İstersek bu kodu bir değişken içinde depolayıp kalıcı hale de getirebiliriz:
>>> b = "; ".join(a)
>>> print b
python; php; perl; C++; Java
En baştaki a adlı liste de böylece bozulmadan kalmış olur:
>>> print a
['python', 'php', 'perl', 'C++', 'Java']
Hatırlarsanız biz bu metodu aslında daha önce de farklı yerlerde kullanmıştık. Mesela “Modüller” konusunu anlatırken de görmüştük bu join() adlı metodu... Orada bunu os.sep.join() şeklinde kullanmıştık.
>>> import os
>>> yol = ["home", "istihza", "Desktop"]
>>> os.sep.join(yol)
'home/istihza/Desktop'
Veya:
>>> yol = ["C:", "Program Files", "Python26"]
>>> os.sep.join(yol)
'C:\\Program Files\\Python26'
Bu kodları sırasıyla şöyle de yazabilirdik:
>>> yol = ["home", "istihza", "Desktop"]
>>> "/".join(yol)
'/home/istihza/Desktop/
>>> yol = ["C:", "Program Files", "Python26"]
>>> "\\".join(yol)
'C:\\Program Files\\Python26'
Hatırlarsanız bu bölümün başında şöyle bir örnek vermiştik:
>>> a = ""
>>> for i in range(10):
... a += str(i)
...
>>> print a
Bu örnek, karakter dizilerinin nasıl birleştirileceğini gösteriyordu. Aynı şeyi join() metodu yardımıyla çok daha verimli bir biçimde de yapabiliriz:
>>> "".join([str(i) for i in range(10)])
'0123456789'
Gördüğünüz gibi, işimizi tek satırda hallettik. Bu örnekteki söz dizimi size biraz tuhaf görünmüş olabilir. Ama hiç endişe etmeyin. Liste Üreteçleri konusunu işlerken bu söz dizimini çok daha ayrıntılı bir şekilde inceleyeceğiz.
translate metodu¶
Bu metot, karakter dizisi metotları içindeki en karmaşık metotlardan birisi olmakla birlikte, zor işleri halletmekte kullanılabilecek olması açısından da bir hayli faydalı bir metottur.
translate() metodu yardımıyla mesela şifreli mesajları çözebiliriz. Yalnız bu metodu string modülündeki maketrans() adlı fonksiyonla birlikte kullanacağız. Bir örnek verelim.
Elimizde şöyle bir karakter dizisi olsun:
"tbyksr çsn jücho elu gloglu"
Bu şifreli mesajı çözmek için de şöyle bir ipucumuz var diyelim:
t = => p s = => o m = => j
Elimizdeki ipucuna göre şifreli mesajdaki “t” harfinin karşılığı “p” olacak. Alfabetik olarak düşünürsek:
“t” harfi, “p” harfine göre, 5 harf geride kalıyor (p, r, s, ş, t)
“s” harfi “o” harfine göre 5 harf geride kalıyor (o, ö, p, r, s)
“j” harfi “m” harfine göre 4 harf geride kalıyor (j, k, l, m)
Bu çıkarımın bizi bir yere götürmeyeceği açık. Çünkü harfler arasında ortak bir ilişki bulamadık. Peki ya alfabedeki Türkçe karakterleri yok sayarsak? Bir de öyle deneyelim:
“t” harfi, “p” harfine göre, 4 harf geride kalıyor (p, r, s, t)
“s” harfi “o” harfine göre 4 harf geride kalıyor (o, p, r, s)
“j” harfi “m” harfine göre 4 harf geride kalıyor (j, k, l, m)
Böylece karakterler arasındaki ilişkiyi tespit etmiş olduk. Şimdi hemen bir metin düzenleyici açıp kodlarımızı yazmaya başlayabiliriz:
# -*- coding: utf8 -*-
Bu satırı açıklamaya gerek yok. Ne olduğunu biliyoruz:
import string
Python modülleri arasından string modülünü içe aktarıyoruz (import):
metin = "tbyksr çsn jücho elu gloglu"
Şifreli metnimizi bir değişkene atayarak sabitliyoruz:
kaynak= "defghijklmnoprstuvyzabc"
hedef = "abcdefghijklmnoprstuvyz"
Burada “kaynak”, şifreli metnin yapısını; “hedef” ise alfabenin normal yapısını temsil ediyor. “kaynak” adlı değişkende “d” harfinden başlamamızın nedeni yukarıda keşfettiğimiz harfler-arası ilişkidir. Dikkat ederseniz, “hedef”teki harfleri, “kaynak”taki harflere göre, her bir harf dört sıra geride kalacak şekilde yazdık. (d -> a, e ->b, gibi...) Dikkat edeceğimiz bir başka nokta ise bunları yazarken Türkçe karakter kullanmamamız gerektiğidir:
cevir = string.maketrans(kaynak,hedef)
Burada ise, yukarıda tanımladığımız harf kümeleri arasında bir çevrim işlemi başlatabilmek için string modülünün maketrans() adlı fonksiyonundan yararlanıyoruz. Bu komut, parantez içinde gösterdiğimiz kaynak değişkenini hedef değişkenine çeviriyor; aslında bu iki harf kümesi arasında bir ilişki kuruyor. Bu işlem sonucunda kaynak ve hedef değişkenleri arasındaki ilişkiyi gösteren bir formül elde etmiş olacağız:
soncevir = metin.translate(cevir)
Bu komut yardımıyla, yukarıda “cevir” olarak belirlediğimiz formülü, “metin” adlı karakter dizisine uyguluyoruz:
print soncevir
Bu komutla da son darbeyi vuruyoruz.
Şimdi bu komutlara topluca bir bakalım:
# -*- coding: utf8 -*-
import string
metin = "tbyksr çsn jücho elu gloglu"
kaynak= "defghijklmnoprstuvyzabc"
hedef = "abcdefghijklmnoprstuvyz"
cevir = string.maketrans(kaynak,hedef)
soncevir = metin.translate(cevir)
print soncevir
Bu programı komut satırından çalıştırdığınızda ne elde ettiniz?
Karakter Dizilerini Parçalarına Ayırma¶
Python’da karakter dizilerini parçalarına ayırmak için iki metottan yararlanacağız. Bunlar partition() ve rpartition() adlı metotlar.
Önce partition() metoduna bakalım.
partition()¶
Bu metot yardımıyla bir karakter dizisini belli bir ölçüte göre üçe bölüyoruz. Örneğin:
>>> a = "istanbul"
>>> a.partition("an")
('ist', 'an', 'bul')
Eğer partition() metoduna parantez içinde verdiğimiz ölçüt karakter dizisi içinde bulunmuyorsa şu sonuçla karşılaşırız:
>>> a = "istanbul"
>>> a.partition("h")
('istanbul', '', '')
rpartition()¶
rpartition() metodu da partition() metodu ile aynı işi yapar, ama yöntemi biraz farklıdır. partition() metodu karakter dizilerini soldan sağa doğru okur. rpartition() metodu ise sağdan sola doğru.. Peki bu durumun ne gibi bir sonucu vardır? Hemen görelim:
>>> b = "istihza"
>>> b.partition("i")
('', 'i', 'stihza')
Gördüğünüz gibi, partition() metodu karakter dizisini ilk “i” harfinden böldü. Şimdi aynı işlemi rpartition() metodu ile yapalım:
>>> b.rpartition("i")
('ist', 'i', 'hza')
rpartition() metodu ise, karakter dizisini sağdan sola doğru okuduğu için ilk “i” harfinden değil, son “i” harfinden böldü karakter dizisini...
partition() ve rpartition() metotları, ölçütün karakter dizisi içinde bulunmadığı durumlarda da farklı tepkiler verir:
>>> b.partition("g")
('istihza', '', '')
>>> b.rpartition("g")
('', '', 'istihza')
Gördüğünüz gibi, partition() metodu boş karakter dizilerini sağa doğru yaslarken, rpartition() metodu sola doğru yasladı.
Karakter Dizilerini Kırpma¶
Python’da karakter dizilerini kırpmak için üç farklı metottan yararlanacağız. Bunlar strip(), rstrip() ve lstrip().
İnceleyeceğimiz ilk metot strip().
strip()¶
Bu metot bir karakter dizisinin başında (solunda) ve sonunda (sağında) yer alan boşluk ve yeni satır (\n) gibi karakterleri siler:
>>> a = " boşluk "
>>> a.strip()
'boşluk'
>>> b = "boşluk\n"
>>> b.strip()
'boşluk'
rstrip()¶
rstrip() metodu bir karakter dizisinin sadece sonunda (sağında) yer alan boşluk ve yeni satır (\n) gibi karakterleri siler:
>>> a = "boşluk "
>>> a.rstrip()
'boşluk'
>>> b = "boşluk\n"
>>> b.rstrip()
'boşluk'
lstrip()¶
lstrip() metodu ise bir karakter dizisinin sadece başında (solunda) yer alan boşluk ve yeni satır (\n) gibi karakterleri siler:
>>> a = " boşluk"
>>> a.lstrip()
'boşluk'
>>> b = "\nboşluk"
>>> b.lstrip()
'boşluk'
Karakter Dizilerini Bölme¶
Bu bölümde, karakter dizilerini bölmeye yarayan üç farklı metottan söz edeceğiz. Bunlar split(), rsplit() ve splitlines().
- split()
- Karakter dizisini soldan sağa doğru okuyarak liste haline getirir.
- rsplit()
- Karakter dizisini sağdan sola doğru okuyarak liste haline getirir.
- splitlines()
- Karakter dizisini satır sonlarından bölerek liste haline getirir.
Anlatmaya önce split() metodundan başlayalım.
split()¶
Bu metot biraz join() metodunun yaptığı işi tersine çevirmeye benzer. Hatırlarsanız join() metodu yardımıyla bir listenin öğelerini karakter dizisi halinde sıralayabiliyorduk:
>>> a = ["Debian", "Pardus", "Ubuntu", "SuSe"]
>>> b = ", ".join(a)
>>> print b
Debian, Pardus, Ubuntu, SuSe
İşte split() metoduyla bu işlemi tersine çevirebiliriz:
>>> yeni = b.split(",")
>>> print yeni
['Debian', ' Pardus', ' Ubuntu', ' SuSe']
Burada karakter dizisini, virgüllerin olduğu kısımlardan böldük. Böylece her karakter dizisi farklı bir liste öğesi haline geldi:
>>> yeni[0]
'Debian'
>>> yeni[1]
'Pardus'
>>> yeni[2]
'Ubuntu'
>>> yeni[3]
'SuSe'
Eğer karakter dizisi içinde virgül yoksa, elbette split() metodunu yukarıdaki şekilde kullanmak istediğiniz şeyi yerine getirmeyecektir:
>>> kardiz = "Python Programlama Dili"
>>> kardiz.split(",")
['Python Programlama Dili']
Yukarıdaki gibi bir karakter dizisi ile karşı karşıya olduğunuzda, bu karakter dizisini virgüllerin olduğu kısımlardan değil, boşlukların olduğu kısımlardan bölmeniz gerekir:
>>> kardiz = "Python Programlama Dili"
>>> kardiz.split(" ")
['Python', 'Programlama', 'Dili']
Hatta eğer isterseniz karakter dizilerini belli harflerin olduğu kısımlardan da bölebilirsiniz:
>>> kardiz = "Python Programlama Dili"
>>> kardiz.split("P")
['', 'ython ', 'rogramlama Dili']
Bu metotta ayrıca isterseniz ölçütün yanısıra ikinci bir parametre daha kullanabilirsiniz:
>>> b = "Debian, Pardus, Ubuntu, SuSe"
>>> c = b.split(",", 1)
>>> print c
['Debian', ' Pardus, Ubuntu, SuSe']
Gördüğünüz gibi, parantez içinde ”,” ölçütünün yanına bir adet “1” sayısı koyduk. Çıktıyı dikkatle incelediğimizde split() metodunun bu parametre yardımıyla karakter dizisi içinde sadece bir adet bölme işlemi yaptığını görüyoruz. Yani oluşan listenin bir öğesi Debian, öteki öğesi de Pardus, Ubuntu, SuSe oldu. Bunu şu şekilde daha açık görebiliriz:
>>> c[0]
'Debian'
>>> c[1]
' Pardus, Ubuntu, SuSe'
Gördüğünüz gibi listenin 0. öğesi Debian iken; listenin 1. öğesi Pardus, Ubuntu, Suse üçlüsü. Yani bu üçlü tek bir karakter dizisi şeklinde tanımlanmış.
Yukarıda tanımladığımız yeni adlı listeyle c adlı listenin uzunluklarını karşılaştırarak durumu daha net görebiliriz:
>>> len(yeni)
4
>>> len(c)
2
Parantez içindeki “1” parametresini değiştirerek kendi kendinize denemeler yapmanız metodu daha iyi anlamanıza yardımcı olacaktır.
rsplit()¶
Bu bölümde inceleyeceğimiz ikinci metodumuzun adı rsplit(). Bu metot yukarıda anlattığımız split() metoduna çok benzer. Hatta tamamen aynı işi yapar. Tek bir farkla: split() metodu karakter dizilerini soldan sağa doğru okurken; rsplit() metodu sağdan sola doğru okur. Önce şöyle bir örnek verip bu iki metodun birbirine ne kadar benzediğini görelim:
>>> a = "www.python.quotaless.com"
>>> a.split(".")
['www', 'python', 'quotaless', 'com']
>>> a.rsplit(".")
['www', 'python', 'quotaless', 'com']
Burada “www.python.quotaless.com” adlı karakter dizisini noktaların olduğu kısımlardan böldük.
Bu örnekte ikisi arasındaki fark pek belli olmasa da, split() metodu soldan sağa doğru okurken, rsplit() metodu sağdan sola doğru okuyor. Daha açık bir örnek verelim:
>>> orneksplit = a.split(".", 1)
>>> print orneksplit
['www', 'python.quotaless.com']
>>> ornekrsplit = a.rsplit(".", 1)
>>> print ornekrsplit
['www.python.quotaless', 'com']
Sanırım bu şekilde ikisi arasındaki fark daha belirgin oldu. Öyle değil diyorsanız bir de şuna bakın:
>>> orneksplit[0]
'www'
>>> ornekrsplit[0]
'www.python.quotaless'
splitlines()¶
Bu bölümün son metodunun adı splitlines(). Bu metot yardımıyla, bir karakter dizisini satır kesme noktalarından bölerek, bölünen öğeleri liste haline getirebiliyoruz:
>>> satir = "Tahir olmak da ayıp değil\nZühre olmak da"
>>> print satir.splitlines()
["Tahir olmak da ayıp değil", 'Zühre olmak da']
Gördüğünüz gibi, splitlines() metodu karakter dizisini “\n” kaçış dizisinin olduğu yerden ikiye böldü...
Böylece karakter dizisi metotlarını bitirmiş olduk. Dikkat ederseniz metot listesi içindeki iki metodu anlatmadık. Bunlar encode ve decode metotları... Bunları unicode konusunu işlerken anlatmak üzere şimdilik bir kenara bırakıyoruz.
Bu konuyu iyice sindirebilmek için kendi kendinize bolca örnek ve denemeler yapmanızı, bu konuyu arada sırada tekrar etmenizi öneririm.
Bölüm Soruları¶
1. Elinizde şöyle bir liste var:
url_list = ['http://www.python.org',
'http://www.istihza.com',
'http://www.google.com',
'http://www.yahoo.com']
Bu listedeki öğelerin başında bulunan http://www kısmını https:// ile değiştirerek şöyle bir liste elde edin:
url_list = ['https://python.org',
'https://istihza.com',
'https://google.com',
'https://yahoo.com']
Ancak betiğin yazımı sırasında hiç bir aşamada ikinci bir liste oluşturmayın. İşlemlerinizi doğrudan url_list adlı liste üzerinde gerçekleştirin.
Hatırlatma: Bir listenin öğeleri üzerinde değişiklik yapmak için şu yolu izliyorduk:
>>> lst = ["Python", "Ruby", "Perl", "C++"]
>>> lst[3] = "C"
>>> print lst
["Python", "Ruby", "Perl", "C"]
2. “Metotlarda Türkçe Karakter Sorunu” başlığı altında, Türkçe karakterleri düzgün bir şekilde büyüten tr_upper() adlı bir fonksiyon tanımlamıştık. Siz de aynı şekilde Türkçe karakterleri düzgün bir şekilde küçülten tr_lower() adlı bir fonksiyon tanımlayın.
3. Konu anlatımı sırasında şöyle bir örnek vermiştik:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
distro = ["Ubuntu", "Debian", "SuSe", "Pardus",
"Fedora", "PCLinuxOS", "Arch", "Gentoo",
"Hadron", "Truva", "Gelecek", "Mandriva",
"Sabayon", "Mint", "Slackware", "Mepis",
"CentOS", "Puppy", "GnewSense", "Ututo",
"Red Hat", "Knoppix", "BackTrack", "Karoshi",
"Kongoni", "DreamLinux", "Yoper", "Slax"]
for k, v in enumerate(distro):
if k % 4 == 0:
print
print "%s"%(v.ljust(15)),
Siz bu örneği print yerine, sys modülünde anlattığımız sys.stdout.write() fonksiyonunu kullanarak yazın. Bu ikisi arasındaki farkların ne olduğunu açıklayın.
4. Kullanıcıdan parola belirlemesini isteyen bir betik yazın. Kullanıcı, belirlediği parolada karakterler arasında boşluk bırakamamalı.
5. Bu bölümde şöyle bir örnek verdiğimizi hatırlıyorsunuz:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
sifreli_metin = """saüipö 1990 ajnjöfcö çv acöc çyaym çkş
üpsnvnvm ücşcğjöfcö hgnkuükşkngö mjzşcm zg fköcokm çkş fknfkş.
trb fkbkokökö tcfg pnoctj, mpnca rışgöknogtk zg sşphşco
hgnkuükşog tyşgdkök ijbncöfjşoctj kng ücöjöcö çv fkn
wköfpwt, höv/nkövx zg ocdpt x hkçk sgm epm ğcşmnj kungüko
tktügok ybgşköfg ecnjucçknogmügfkş. fpncajtjanc ügm çkş
sncüğpşofc hgnkuükşfkıkökb çkş saüipö vahvncoctj, ybgşköfg
ike çkş fgıkukmnkm acsocac hgşgm pnocfcö zgac myeym
fgıkukmnkmngşng çcumc sncüğpşoncşfc fc ecnjucçkngdgmükş."""
sozluk = {"a": "y", "b": "z", "c": "a",
"ç": "b", "d": "c", "e": "ç",
"f": "d", "g": "e", "ğ": "f",
"h": "g", "ı": "ğ", "i": "h",
"j": "ı", "k": "i", "l": "j",
"m": "k", "n": "l", "o": "m",
"ö": "n", "p": "o", "r": "ö",
"s": "p", "ş": "r", "t": "s",
"u": "ş", "ü": "t", "v": "u",
"y": "ü", "z": "v"}
sifresiz_metin = ""
for harf in sifreli_metin:
sifresiz_metin += sozluk.get(harf, harf)
print sifresiz_metin
Siz şimdi bu örneği bir de join() metodunu kullanarak yazmayı deneyin. Eğer yazamazsanız endişe etmeyin, çünkü, daha önce de söylediğimiz gibi, bu örneği join() metodunu kullanarak rahatlıkla yazmanızı sağlayacak bilgiyi birkaç bölüm sonra daha ayrıntılı bir şekilde edineceğiz.