koddla

Yazılımcıları bilgi ile güçlendirir.

Python101 – Özyineleme

Özyineleme

Özyinelemeli işlev, yine kendisini çağıran bir işlevdir.

Özyinelemeye giriş

Şimdiye kadar Python’da diğer işlevleri çağıran işlevler gördük. Ancak, bir işlevin kendisini çağırması da mümkündür. Basit bir örneğe bakalım.

# Program by Mitchell Aikens
# No Copyright
# 2010

num = 0

def main():
    counter(num)

def counter(num):
    print(num)
    num += 1
    counter(num)

main()

Bu programı IDLE’de çalıştırırsanız, sonsuza kadar çalışır. Döngüyü durdurmanın tek yolu, klavyenizde Ctrl + C tuşlarına basarak yürütmeyi kesmek olacaktır. Bu sonsuz bir özyineleme örneğidir. (Bazı kullanıcılar, geçerli IDLE sisteminde bir aksaklık olduğunu ve Ctrl + C tarafından yükseltilen özel durumun da döngüye başlamasına neden olduğunu bildirmişlerdi. Bu durumda, Ctrl + F6 tuşlarına basın ve IDLE kabuğunu yeniden başlatın.)

Özyinelemenin, bir döngüyle aynı şeyi yaptığı tartışılabilir. Bazı durumlarda bu doğru olacaktır. Yine de, döngülerin uygun olmayabileceği çok geçerli başka kullanım alanlarında özyinelemeler gayet uygun olacaktır.

Özyinelemeler döngüler gibi kontrol edilebilir. Kontrollü döngü örneğine bakalım.

# Program by Mitchell Aikens
# No copyright
# 2012
def main():
    loopnum = int(input("How many times would you like to loop?\n"))
    counter = 1
    recurr(loopnum,counter)

def recurr(loopnum,counter):
    if loopnum > 0:
        print("This is loop iteration",counter)
        recurr(loopnum - 1,counter + 1)
    else:
        print("The loop is complete.")

main()

Yukarıdakiler özyineleme sayısını denetlemek için bağımsız değişkenler/parametreler kullanır. İşlevler hakkında zaten bildiklerinizi kullanıp programın akışını takip etmeyi deneyin. Sorun yaşıyorsanız, lütfen gelişmiş fonksiyonlar makalesine bakın.

Özyinelemenin Pratik Uygulamaları

Genellikle, özyineleme ileri bir bilgisayar bilimi düzeyinde incelenir. Özyineleme daha küçük, aynı sorunlara bölünebilen karmaşık sorunları çözmek için kullanılır. Bir sorunu çözmek için özyineleme gerekli olmayabilir. Özyineleme ile çözülebilecek sorunlar, büyük olasılıkla döngülerle de çözülebilir. Ayrıca, bir döngü özyinelemeli bir işlevden daha verimli de olabilir. Özyinelemeli işlevler döngülerden daha fazla bellek ve kaynak gerektirir, bu da onları birçok durumda daha az verimli hale getirir. Bu kullanım gereksinimi bazen overhead olarak adlandırılır. Şöyle düşünüyor olabilirsiniz, “Peki neden bununla uğraşalım ki? Bir döngü kullanıp bitirebilirim. Döngü yapmayı zaten biliyorum ve bu özyineleme işi çok daha fazla iş gibi görünüyor.” Bu düşünce anlaşılabilir, ancak tamamen doğru değil. Karmaşık sorunları çözerken, özyinelemeli bir işlev bazen daha kolay ve daha hızlı oluşturulup kodlanabilir.

Şu iki kuralı düşünün:

  • Sorunu şimdi, özyineleme olmadan çözebilirsem, işlev basitçe bir değer döndürür.
  • Özyineleme olmadan şimdi sorunu çözemezsem, işlev sorunu daha küçük ve benzer bir şeye indirger ve sorunu çözmek için kendisini çağırır.

Bunu ortak bir matematiksel kavram olan faktöriyel kullanarak uygulayalım. Matematikteki faktöriyele aşina değilseniz, bu yazıya bakabilirsiniz.

n sayısının faktöriyeli n! ile ifade edilir.

İşte bazı temel faktöriyel kuralları.

n = 0 ise n! = 1, n > 0 ise n! = 1 x 2 x 3 x … x n

Örneğin, 9 sayısının faktöriyeline bakalım.

9! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9

Özyineleme yöntemiyle kullanıcı tarafından girilen herhangi bir sayının çarpanını hesaplayan bir programa bakalım.

def main():
    num = int(input("Please enter a non-negative integer.\n"))
    fact = factorial(num)
    print("The factorial of",num,"is",fact)

def factorial(num):
    if num == 0:
        return  1
    else:
        return num * factorial(num - 1)

main()

Özyinelemeler, üreteçler adı verilen gelişmiş bir konuda da yararlıdır. Diyelim ki 1,2,1,3,1,2,1,4,1,2… serisini oluşturmak istiyoruz. O zaman aşağıdaki koda ihtiyacımız olacaktır:

def crazy(min_):
    yield min_
    g=crazy(min_+1)
    while True:
        yield next(g)
        yield min_

i=crazy(1)

bir sonraki öğeyi almak için next(i) komutunu kullanıyoruz.

Not: Burada yield fonksiyonunu kullandık. Bu işlev özyineleme için gerekli olmasa da yield’ın ne işe yaradığını öğrenmek için bu makaleyi takip edebilirsiniz.

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top