- For döngüsü ile aşağıdaki gibi iki karakter dizisi
olduğunu varsayarak her iki karakter dizisinde blulunan
harfleri ekrana basan programı yazınız
ilk=“sdlkfjsldkfjwernwömfndsömcnösmdnfsldkfjsld”
iki=“dskcjsdlkcjsdslrejfdslvkjdxlk”
metin1 = input("Birinci metninizi giriniz :")
metin2 = input("İkinci metninizi giriniz :")
liste = []
anahtar = 0
for harf in metin1:
if harf == " ":
break
if harf in metin2:
if harf in liste:
break
liste.append(harf)
print(liste)
amatörce birşey yaptım ama işini görür
ilk = "sdlkfjsldkfjwernwömfndsömcnösmdnfsldkfjsld"
iki = "dskcjsdlkcjsdslrejfdslvkjdxlk"
i = [q for q in ilk]
l = [q_1 for q_1 in iki]
c = input("İlk harfi giriniz")
p = input("İkinci harfi giriniz")
if c and p in i and l:
print("İki harfte bulunuyor.")
else:
print("Biri ya da hiçbiri bulunmuyor ") # Ayriyetten bir daha statement yapmak istemedim siz ekliyebilirsiniz.
List Comprehensions
dediğimiz yapıyı kullanarak yapabiliriz.
Buna gerek yok. Performans düşürür. i = list(ilk)
ile aynı şey zaten. Listelere de gerek yok, çünkü karakter dizileri de iterator’dur zaten.
@vahvah , konu başlığını daha anlamlı bir başlıkla değiştirebilir misiniz?
direk karakter dizisi içerisindende yapılabilir liste kullandığı için kullandım yoksa direk
girdi istenip if girdi in … şeklinde sağlanabilir.
>>> timeit.timeit("[q for q in a]",globals=globals())
0.5007499419989472
>>> timeit.timeit("list(a)",globals=globals())
0.2679310639996402
arada dehşet fark var aynı şekilde copy methodunda v.s de geçerli bir [:] şeklinde kopyalamak bir de method kullanıp kopyalamak var o zaman da methodlar her zaman daha seri çalışıyor
Gormez, ornek metinde bile calismiyor.
Evet:
print([h for h in ilk if h in iki])
Tek satıra düşürmek performansı yine arttıracaktır fakat yine de list methodu daha seri çalışıyor list kullanacaksak da 0 25 0.25 yine 0.50 olacak bu şekilde de aslında aynı mantığa geliyor performans acısından
Tek satır olmanın performansla alakası yok. Yorumlayıcı fazladan yeni satır karakteri okuyor o kadar.
Deneyelim istiyorsanız var mi yok mu yazın bir tek bir de aralarına boşluk ekliyerek
Kısa olan kod mantıklı olan koddur kısacası bir işi kısa halletmek yani az satırla çalıştırmak daha hizli olacaktır
teşekkür ederim mmmmmmm
Kodun uzunluğunun performansıyla zerre kadar alakası yok. Kısa bir kod onunla aynı işi yapan uzun koda göre hızlı da olabilir, yavaş da. Bu tamamen kod ile alakalı bir şey.
Çok basit bir örnek vereyim. İçinde 1 milyon eleman bulunan ve sıralı olan bir dizide, düz for döngüsü ile arama yapmaya kalkarsan geçen zaman 1 milyon komut süresi olur. Kod çok kısa
def search(arr, x):
for i in range(len(arr)):
if arr[i] == x:
return i
return -1
Ama aynı kodu binary search ile yeniden yazarsan kodun uzar ama süre logaritmik olarak azalır.
def binarySearch (arr, l, r, x):
if r >= l:
mid = l + (r - l)/2
if arr[mid] == x:
return mid
elif arr[mid] > x:
return binarySearch(arr, l, mid-1, x)
else:
return binarySearch(arr, mid + 1, r, x)
else:
return -1
Çok basit bir örnek, daha nice veri yapıları var bunun gibi. Önemli olan, yukarıda da denildiği gibi, algoritmadır. Satır sayısı önemli değildir.
Neden logaritmik olarak azalıyor? ( okulda Henüz logaritmaya geçmedik.)
mid
değişkeninin veri tipini int
yapmak gerekiyor. Bir de l
ve r
parametrelerine tam olarak ne yazılması gerekiyor?
Mesela paylaştığınız kodlarla bir kaç deneme yapayım dedim, çok bir fark görmedim.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import timeit
def f1(arr, x):
for i in range(len(arr)):
if arr[i] == x:
return i
return -1
def f2(arr, l, r, x):
if r >= l:
mid = int(l + (r - l)/2)
if arr[mid] == x:
return mid
elif arr[mid] > x:
return f2(arr, l, mid-1, x)
else:
return f2(arr, mid + 1, r, x)
return -1
arr = [i for i in range(10 ** 6)]
print(timeit.timeit(f"{f1(arr, 57821)}"))
# Sonuç: 0.010027280000031169
print(timeit.timeit(f"{f2(arr, 0, 10 ** 6, 57821)}"))
# Sonuç: 0.010062176000246836
Çünkü her seferinde dizinin bir yarısını eliyor. Sadece bir kısmına bakıyor. Sürekli olarak da 2’ye bölüyor. Logaritmayı 2 tabanında alıyoruz tabi bu arada.
log2 1000000 = 19.93
Öncelikle bahsettiğim durum en kötü durum için, yani aradığımız elemanın en sonda olma ihtimali. Bu yüzden aranan değere, dizinin sonunda bulunan değeri yazıyorum. l ve r değerlerine, arama yapılan dizinin baş ve son indis değerleri verilecek. Kodu şu şekilde düzelttiğim zaman, ben de gözle görülür bir fark oluşuyor.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import timeit
kod1 = """
def f1(arr, x):
for i in range(len(arr)):
if arr[i] == x:
return i
return -1
arr = [i for i in range(10 ** 6)]
f1(arr, 10**6-1)
"""
kod2 = """
def f2(arr, l, r, x):
if r >= l:
mid = int(l + (r - l)/2)
if arr[mid] == x:
return mid
elif arr[mid] > x:
return f2(arr, l, mid-1, x)
else:
return f2(arr, mid + 1, r, x)
return -1
arr = [i for i in range(10 ** 6)]
f2(arr, 0,10**6,10**6-1)
"""
print(timeit.timeit(stmt = kod1,number=2))
# 0.7054800316010079
print(timeit.timeit(stmt = kod2,number=2))
# 0.29855470813155927
Ek olarak, zamandan bağımsız bir şekilde iki fonksiyonun kaç kez karşılaştırma işlemi yaptığını da şöyle basit bir şekilde görebiliriz
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def f1(arr, x):
global comparison
for i in range(len(arr)):
comparison += 1
if arr[i] == x:
return i
return -1
def f2(arr, l, r, x):
global comparison
comparison += 1
if r >= l:
mid = int(l + (r - l)/2)
if arr[mid] == x:
return mid
elif arr[mid] > x:
return f2(arr, l, mid-1, x)
else:
return f2(arr, mid + 1, r, x)
return -1
arr = [i for i in range(10 ** 6)]
comparison = 0
f1(arr,10**6-1)
print("Comparison 1: {}".format(comparison))
# sonuç: 1000000
comparison = 0
f2(arr,0,10**6,10**6-1)
print("Comparison 2: {}".format(comparison))
# sonuç: 19
Aslında mantık olarak 2. fonksiyon belirlenen rakamı bulmaya çalışırken daha az işlem gerçekleştirir.
def f1(n: int, k: int):
for i in range(n):
if i == k:
return 0
def f2(_min: int, _max: int, k: int):
mid = (_min + _max) / 2
if k == mid:
return 0
elif k > mid:
return f2(_min=mid + 1, _max=_max, k=k)
elif k < mid:
return f2(_min=_min, _max=mid - 1, k=k)
Aynen öyle. Öncelikle dizinin ortasına bakar ve aranan değer burada değilse, aranan değerin küçük veya büyük olma durumuna göre sağ veya sol kısımdan birine bakar. Böylece arama işlemi dizinin yarısında devam ediyor. Her recursive çalıştığında dizinin bir yarısını eledigi için daha az işlem yapmış oluyor.