koddla

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

Python’da yazıyı/dizeyi ters çevirme nasıl yapılır?

Python’da yerleşik bir ters çevirme fonksiyonu bulunmuyor. Peki bu işlemi uygulamanın en iyi yolu nedir?

>>> 'hello world'[::-1]
'dlrow olleh'

Bu sözdizimi genişletilmiş dilim sözdizimidir. [başlangıç:son:adım] sistemine göre çalışır. Son kısmına -1 yazıldığında bir dizeyi tersine çevirir.

Genişletilmiş dilim yöntemi en hızlı şekilde sonuca ulaştırır. Bunun yanında .join de kullanılabilir;

>>> ''.join(reversed('a string'))
'gnirts a'

Daha okunaklı bir çözüm ise bir fonksiyon tanımlayarak

def reversed_string(a_string):
    return a_string[::-1]

ve sonrasında:

>>> reversed_string('a_string')
'gnirts_a'

fonksiyonu çağırarak elde edilebilir.

Daha uzun açıklama

Akademik bir açıklama için lütfen okumaya devam edin.

Python’un str nesnesinde yerleşik bir terse çevirme fonksyionu yoktur.

Python dizeleri ile ilgili bilmemiz gereken birkaç şey:

  1. Python’da dizeler değişmez. Bir dizenin değerini değiştirmek dizeyi değiştirmez. Yeni bir dize yaratır.
  2. Dizeler dilimlenebilir. Bir dizeyi dilimleme, dizenin bir noktasından geriye veya ileriye doğru, verilen artışlarla yada başka bir noktaya doğru yeni bir dize verir. Burada dize bir dilim objesi kullanır.

Ayraçlar iki nokta üst üste aracılığı ile bir dilim oluşturur:

    string[başlangıç:son:adım]

Ayraçların dışında bir dilim oluşturmak için bir dilim nesnesi (slice) oluşturmanız gerekir:

    slice_obj = slice(start, stop, step)
    string[slice_obj]

Okunabilir bir yaklaşım:

Aşağıdaki yöntem okunabilir olsa da, .join metodunu çağırmak bir dize fonksiyonunu çağırmak demektir ve nispeten yavaştır.

def reverse_string_readable_answer(string):
    return ''.join(reversed(string))

En performanslı yaklaşım:

Çok daha hızlısı ters dilim kullanmaktır:

'foo'[::-1]

Peki bu yöntemi nasıl daha okunabilir ve anlaşılabilir hale getirebiliriz? Bir dilim nesnesi oluşturalım, açıklayıcı bir ad verelim ve alt simge gösterimine geçirelim.

baslangic = son = None
adim = -1
reverse_slice = slice(baslangic, son, adim)
'foo'[reverse_slice]

Fonksiyon olarak uygula

Bunu bir işlev olarak uygulayalım:

def reversed_string(a_string):
    return a_string[::-1]

Ve basitçe aşağıdaki gibi kullanalım:

reversed_string('foo')

Muhtemelen sizden istenen:

Bir eğitmeniniz varsa, muhtemelen boş bir dizeyle başlamanızı ve eskisinden yeni bir dize oluşturmanızı isteyecektir. Bunu, bir while döngüsü kullanarak saf sözdizimi ve hazır bilgilerle yapabilirsiniz:

def reverse_a_string_slowly(a_string):
    new_string = ''
    index = len(a_string)
    while index:
        index -= 1                    # index = index - 1
        new_string += a_string[index] # new_string = new_string + character
    return new_string

Bu teorik olarak kötüdür, çünkü unutmayın, dizeler değişmezdir – bu yüzden bir karakterin üzerine bir karakter yapıştırıyor gibi göründüğünüz her zaman, teorik olarak her seferinde yeni bir dize yaratırsınız! Bununla birlikte, CPython, bu gibi durumlarda bunu nasıl optimize edeceğini iyi bilir.

En İyi Uygulama

Teorik olarak en iyisi, alt dizelerinizi bir listede toplamak ve daha sonra bunları birleştirmektir:

def reverse_a_string_more_slowly(a_string):
    new_strings = []
    index = len(a_string)
    while index:
        index -= 1                       
        new_strings.append(a_string[index])
    return ''.join(new_strings)

Ancak, CPython için aşağıdaki zamanlamalarda göreceğimiz gibi, bu aslında daha uzun sürer, çünkü CPython dize birleştirmeyi optimize edebilir.

Zamanlama

Zamanlamalar:

>>> a_string = 'amanaplanacanalpanama' * 10
>>> min(timeit.repeat(lambda: reverse_string_readable_answer(a_string)))
10.38789987564087
>>> min(timeit.repeat(lambda: reversed_string(a_string)))
0.6622700691223145
>>> min(timeit.repeat(lambda: reverse_a_string_slowly(a_string)))
25.756799936294556
>>> min(timeit.repeat(lambda: reverse_a_string_more_slowly(a_string)))
38.73570013046265

Bir yanıt yazın

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

Back to top