Python ile Programlamaya Giris Paralel Listeler

Python ile Programlamaya Giris
Ders 7
Paralel Listeler
Geçen ders for döngüsü ile bir listenin elemanlarini saydirmayi gördük. Ayni
sekilde bir for döngüsü ile iki ve daha fazla listenin elemanlarini saydirabiliriz.
Örnek 1
Örnek olarak iki dizinin ayni indeksdeki elemanlarini toplayip yeni bir dizi olusturan
sum_items fonksiyonunu inceleyelim. Mesela [1, 2] ve [3, 4] gibi iki
dizi verildiginde sum_items fonksiyonu [4, 5] dizisini geri vermeli.
Fonksiyonu yazmadan önce bu fonksiyonu kullanacak programcilar ile bir
anlasma yapilacak. Anlasmaya göre verilen iki dizinin eleman sayilari ayni olacak.
def sum_items(list1, list2):
sum_list = []
for i in range(len(list1)):
sum_list.append(list1[i] + list2[i])
return sum_list
Fonksiyon tabiki iki parametre aliyor, birinci dizi ve ikinci dizi. sum_list
akümülatör degisken bos bir diziye esitleniyor. Döngü sifirdan len(list1) 'e
kadar, yani verilen ilk dizinin eleman sayisinin bir eksigine kadar çalisiyor.
Dolayisiyla ilk calistiginda list1[0] + list2[0] 'yi topluyor, ikinci
çalistiginda list1[1] + list2[1] topluyor vs.
Ilk basta yapilan anlasmaya göre list1 ve list2 nin eleman sayilari esit
olmali. Buna göre yukaridaki örnekte len(list1) yerine len(list2) de
kullanilabilirdi.
sum_items fonksiyonu asagidaki gibi kullanilabilir.
>>> sum_items([1, 2, 3], [4, 5, 6])
[5, 7, 9]
Alistirma: sum_items([1, 2], [4, 5, 6]) olarak çalistirirsak sonuç ne
olur? sum_items([1, 2, 3], [4, 5]) olarak çalistirirsak sonuç ne olur?
Örnek 2
Iki stringin ayni indekste bulunan ayni harflerin sayisini veren
count_matching fonksiyonunu ele alalim.
>>> count_matching("elalem","eldiven")
2
>>> count_matching("elalem","elelem")
5
Bir önceki örnekte oldugu gibi bu fonksiyon da dogru çalisabilmesi çin ön kosul
olarak ayni uzunlukta iki string bekliyor.
def count_matching(str1, str2):
num_matching = 0
for i in range(len(str1)):
if str1[i] == str2[i]:
num_matching = num_matching + 1
return num_matching
Bu örnek bi öncekinden çok farkli degil. Yine akümülatör degisken var. Bu
degiskenin ilk degeri sifir ve str1[i] == str2[i] kosulu saglandigi sürece
bir artiriliyor. En sonunda akümülatör degisken geriye veriliyor.
Bu örnek ayni zamanda iki ayni uzunluktaki protein zincirinin ayni siradaki kaç
tane amino asitlerinin esit oldugunu bulabilir.
>>> count_matching("ALDDGVUK","GLUDVVGK")
4
Alistirma: count_matching fonksiyonunu iki string yerine iki list için
kullanmak isteseydik hangi degisiklikleri yapmamiz gerekirdi? Bu örnegin farkli
uzunluktaki iki string için çalisabilmesi için hangi degisikligi yapmak gerekir?
Iç içe döngüler
Bir döngü için baska bir döngü çalisirsa buna iç içe döngüler denir.
for i in range(10,13):
for j in range(2):
print(i,j)
Yukaridaki örnekte iki tane döngü iç içe. Disindaki döngü 10,11 ve 12 için çalisiyor
içerideki döngü ise 0,1 için çalisiyor. Bu örnegin çiktisi asagidaki gibidir.
10
10
11
11
12
12
0
1
0
1
0
1
Distaki döngü 3 kere, içteki döngü her seferinde 2 defa çalisiyor. Buna göre
print fonksiyonu toplamda 3 x 2 = 6 defa çalisir.
Iç içe döngülerin çok kullanildigi durumlardan birisi iç içe listelerin oldugu zaman.
Mesela [[30, 60, 90], [40, 80], [60, 100, 50]] listesindeki her bir
eleman yine bir listeyi temsil ediyor. Diyelimki bu liste bir ögrencinin her bir
dersten aldigi notlar olsun. Listenin ilk elemani, yani [30, 60, 90] , ingilizce
dersinin notlari olsun, ikinci elemani, yani [40, 80] , biyoloji dersinin notlari
olsun vs. Amacimiz bu listeyi kullanarak her dersin ortalamasini bulan ve bunlari
bir liste seklinde gösteren programi yazmak olsun. Yani yukaridaki listeye göre
bulunmasini istedigimiz liste [60, 60, 70] seklinde olacaktir.
Bu örnegi çözerken iç içe listelerden faydalanacagiz. Öncelikle bir listedeki
elemanlarin ortalamasini bulan program parçasini yazalim.
grade_list = [30, 60, 90]
total = 0
for mark in grade_list:
total = total + mark
print(total/len(grade_list))
Bu programin sonucu print ile ekrana yazilan 60.0 degeri olacaktir.
total akümülatör degiskenimiz ve grade_list dizisindeki herbir degeri
topluyor. Daha sonra bu deger len(grade_list) sonucuna, yani
grade_list dizisinin eleman sayisina, bölünüyor. Böylelikle grade_list
dizindeki notlarin aritmetik ortalamasi bulunmus oluyor.
Fakat bu istedigimiz programin sadece bir bölümü. Asil yapilmasi gereken her bir
ders için not ortalamasini bulmak.
Notlarin tutuldugu dizi asagidaki gibi olsun.
grades = [[30, 60, 90], [40, 80], [60, 100, 50]]
Her bir ders için not ortalamasini bulan programin ilk iskeleti asagidaki gibi olabilir.
avg_list = []
for grade_list in grades:
# 1. grade_list dizisinin ortalamasini bul
# 2. ortalamayi avg_list listesine ekle
Burada 1. ve 2. ile verilen kisimlari yazacagiz. Istedigimiz sonuç, yani her dersin
ortalamasi, avg_list dizisinde toplanacak.
Aslinda 1. yazan yerin kodunu yukarida hazirlamistik. Simdi hepsini yerine
yazalim.
avg_list = []
for grade_list in grades:
# 1. grade_list dizisinin ortalamasini bul
total = 0
for mark in grade_list:
total = total + mark
# 2. ortalamayi avg_list listesine ekle
avg_list.append(total/len(grade_list))
Burada dikkat çekilmesi gereken önemli bir nokta da total akümülatörüdür.
Bu degisken içteki döngüye girmeden once her seferinde sifirlaniyor. total
degiskeninin çünkü sadece o anda aktuel olan dersin notlarinin toplamini
içermesini istiyoruz.
Dosya Okuma Islemleri
Su ana kadar yaptigimiz islemler hep bilgisayarin hafizasinda tutuluyordu.
Program kapatildiginda bilgiler siliniyor, program açildiginda bilgileri tekrar elimizle
girmemiz gerekiyordu. Bu bölümde bilgileri dosyadan okumayi görecegiz.
Bir dosyayi açmak için open(filename, mode) dahili fonksiyonunu
kullanacagiz. Burada filename açmak istedigimiz dosyanin yeri, mode
dosyayi açmak istedigimiz modu belirtir.
Dosya üç farkli modda açilabilir.
Mod
Açiklama
'r'
Dosya okunmak için açilacak
'w'
'a'
Dosya yazmak için açilacak (açilirken önce dosyanin içerigi
silinecek)
Dosyaya eklemek için açilacak (açilirken dosyanin içerigi
silinmeyecek)
Eger dosya programi çalistirdigimiz dizinde ise sadece dosyanin ismini vermek
yeterli olacaktir. Eger dosya programin çalistigi dizinden farkli bir yerde ise
dosyanin tüm yerini belirtmemiz gerekir.
Örnek olarak asagidaki dosyayi masaüstüneki atoms.txt dosyasini okuyalim.
ATOM
ATOM
ATOM
ATOM
12
13
14
15
3.4 5.6 7.0
4.4 5.5 17.43
1.75 1.6 3.4
3.23 3.9 1.23
Dosyanin yerini dosya_isim degiskeninde tutalim. Bunu daha sonra tekrar
tekrar yazmamak için yapiyoruz.
dosya_isim = "/Users/ayaz/Desktop/atoms.txt"
Dosyayi sadece okumak için açalim.
dosya = open(dosya_isim, 'r')
Burada dosya açilan dosyayi gösteren bir degisken.
Alistirma: dir(dosya) ile dosya degikeninin metodlarini inceleyiniz.
Gerekirse help fonksiyonundan yararlanarak metodlarin islevlerini ögreniniz.
readline() metodu açilan dosyadan bir satir okumak için kullanilir.
>>> dosya.readline()
'ATOM 12 3.4 5.6 7.0\n'
Ayni metodu birden fazla kez çagirabiliriz. Her seferinde bir sonraki satiri okur.
>>> dosya.readline()
'ATOM 13 4.4 5.5 17.43\n'
>>> dosya.readline()
'ATOM 14 1.75 1.6 3.4\n'
>>> dosya.readline()
'ATOM 15 3.23 3.9 1.23'
>>> dosya.readline()
''
Dosyanin tüm içerigi okunduktan sonra readline() metodu bos string geri
verir. readline() metodunun bos string verdigi tek durum dosyada okunacak
baska birsey kalmadigi durumdur.
( readline() satir sonunu da ('\n') okudugunu farkettiniz mi? Bos satirlarda
dahi satir sonu okunur. O zaman readline() ile okunan stringing degeri
'\n' olur.)
Yukaridaki bilgilere göre bir dosyadan satir satir okumak için basit bir while
dögüsü kullanabiliriz. Bunun için önce dosyayi kapatalim ve tekrar açalim. Bu
sayede dosyayi tekrar bastan okuyabiliriz.
>>> dosya.close()
>>> dosya = open(dosya_isim, 'r')
Döngüde sadece satirlari ekrana yazdiralim.
>>> line = dosya.readline()
>>> while line != '':
print(line)
line = dosya.readline()
Bu programin sonucu asagidaki gibidir.
ATOM 12 3.4 5.6 7.0
ATOM 13 4.4 5.5 17.43
ATOM 14 1.75 1.6 3.4
ATOM 15 3.23 3.9 1.23
Alistirma: Dosyada her satirdan sonra bosluk olmadigi halde yukaridaki
programin çiktisinda neden aralarda hep bir bos satir var? Nedenini bulmaya
çalisin. Bu davranisi nasil engelleyebiliriz?
readline() dosyadan satir satir okumamizi sagliyor. for döngüsü ile
dosyanin satirlarini asagidaki gibi de okutabilirdik.
Yine önce dosyayi kapatip tekrar açalim.
>>> dosya.close()
>>> dosya = open(dosya_isim, 'r')
Döngüyü in operatörü ile kullanacagiz.
for line in dosya:
print(line)
Bu döngünün sonucu yukaridaki sonuç ile ayni olur.
Eger okuyacagimiz dosya çok büyük degilse tüm dosyayi tek bir read()
metoduyla bir string olarak okutabiliriz. Tabi önce dosyayi tekrar kapatip açmayi
unutmayin.
>>> print(dosya.read())
ATOM 12 3.4 5.6 7.0
ATOM 13 4.4 5.5 17.43
ATOM 14 1.75 1.6 3.4
ATOM 15 3.23 3.9 1.23
Bir baska okuma yöntemi de readlines() metodunu kullanarak okumak. Her
satiri bir dizinin elemani olarak okutacagiz.
>>> lines = dosya.readlines()
>>> lines[0]
'ATOM 12 3.4 5.6 7.0\n'
>>> lines[2]
'ATOM 14 1.75 1.6 3.4\n'
Dosyalar için tanimlanan readlines() metodu ile stringler için tanimlanan
split() metodu ile dosyanin hem satirlarini hem de sütunlarini okuyabiliriz.
>>> lines[0].split(" ")
['ATOM', '12', '3.4', '5.6', '7.0\n']
Yukaridaki örnek dosyanin ilk satirini bosluk karakterine göre parçalayip bir liste
olusturuyor.