Pertanyaan Membalikkan string dengan Python


Tidak ada yang dibangun reverse berfungsi untuk Python str obyek. Apa cara terbaik untuk menerapkan metode ini?

Jika memberikan jawaban yang sangat singkat, tolong jelaskan efisiensinya. Misalnya, apakah str objek diubah menjadi objek yang berbeda, dll.


1069
2018-05-31 02:10


asal


Jawaban:


Bagaimana tentang:

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

Ini adalah potongan diperpanjang sintaksis. Ia bekerja dengan melakukan [begin:end:step] - dengan meninggalkan memulai dan mengakhiri dan menetapkan langkah -1, itu membalikkan string.


2216
2018-05-31 02:11



@ Paolo s[::-1] tercepat; pendekatan yang lebih lambat (mungkin lebih mudah dibaca, tapi itu bisa diperdebatkan) ''.join(reversed(s)).


217
2018-05-31 02:13



Apa cara terbaik untuk menerapkan fungsi reverse untuk string?

Pengalaman saya sendiri dengan pertanyaan ini bersifat akademis. Namun, jika Anda seorang pro mencari jawaban cepat, gunakan irisan yang langkah demi langkah -1:

>>> 'a string'[::-1]
'gnirts a'

atau lebih mudah dibaca (tetapi lebih lambat karena metode pencarian nama dan fakta yang bergabung membentuk daftar ketika diberi iterator), str.join:

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

atau untuk keterbacaan dan usabilitas, masukkan irisan ke dalam fungsi

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

lalu:

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

Penjelasan lebih panjang

Jika Anda tertarik dengan eksposisi akademik, silakan baca terus.

Tidak ada fungsi terbalik bawaan di objek str Python.

Berikut ini beberapa hal tentang string Python yang harus Anda ketahui:

  1. Dengan Python, string tidak dapat diubah. Mengubah string tidak mengubah string. Ini menciptakan yang baru.

  2. String dapat diiris. Mengiris string memberi Anda string baru dari satu titik dalam string, ke belakang atau ke depan, ke titik lain, dengan penambahan tertentu. Mereka mengambil notasi slice atau objek slice dalam subscript:

    string[subscript]
    

Subskrip membuat irisan dengan memasukkan tanda titik dua di dalam kurung kurawal:

    string[start:stop:step]

Untuk membuat potongan di luar kurung, Anda harus membuat objek irisan:

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

Pendekatan yang mudah dibaca:

Sementara ''.join(reversed('foo')) dapat dibaca, itu membutuhkan memanggil metode string, str.join, pada fungsi lain yang disebut, yang bisa agak relatif lambat. Mari kita menempatkan ini dalam suatu fungsi - kita akan kembali ke sana:

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

Pendekatan yang paling berkinerja:

Lebih cepat menggunakan potongan terbalik:

'foo'[::-1]

Tapi bagaimana kita bisa membuat ini lebih mudah dibaca dan dimengerti oleh seseorang yang kurang akrab dengan irisan atau maksud dari si penulis asli? Mari kita buat objek slice di luar notasi subscript, beri nama deskriptif, dan berikan ke notasi subscript.

start = stop = None
step = -1
reverse_slice = slice(start, stop, step)
'foo'[reverse_slice]

Terapkan sebagai Fungsi

Untuk benar-benar menerapkan ini sebagai fungsi, saya pikir itu cukup semantik untuk hanya menggunakan nama deskriptif:

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

Dan penggunaannya sederhana:

reversed_string('foo')

Apa yang mungkin diinginkan guru Anda:

Jika Anda memiliki instruktur, mereka mungkin ingin Anda memulai dengan string kosong, dan membangun string baru dari yang lama. Anda dapat melakukan ini dengan sintaks dan literal murni menggunakan loop while:

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

Ini secara teoritis buruk karena, ingat, string tidak dapat diubah - jadi setiap kali terlihat Anda menambahkan karakter ke karakter Anda new_string, secara teoritis membuat string baru setiap waktu! Namun, CPython tahu bagaimana mengoptimalkan ini dalam kasus-kasus tertentu, di mana kasus sepele ini adalah satu.

Praktek terbaik

Secara teoritis lebih baik adalah mengumpulkan substring Anda dalam daftar, dan bergabung dengan mereka nanti:

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)

Namun, seperti yang akan kita lihat pada timing di bawah ini untuk CPython, ini sebenarnya membutuhkan waktu lebih lama, karena CPython dapat mengoptimalkan penggabungan string.

Pengaturan waktu

Berikut pengaturan waktunya:

>>> 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

CPython mengoptimalkan penggabungan string, sedangkan implementasi lainnya mungkin tidak:

... jangan bergantung pada implementasi efisien CPython untuk rangkaian string in-place untuk pernyataan dalam bentuk a + = b atau a = a + b. Pengoptimalan ini rapuh bahkan di CPython (hanya berfungsi untuk beberapa jenis) dan tidak ada sama sekali dalam implementasi yang tidak menggunakan penghitungan ulang. Dalam bagian pustaka yang peka terhadap kinerja, bentuk '' .join () sebaiknya digunakan sebagai gantinya. Ini akan memastikan bahwa penggabungan terjadi dalam waktu linier di berbagai implementasi.


168
2018-01-08 15:32



Jawaban Cepat (TL; DR)

Contoh

### example01 -------------------
mystring  =   'coup_ate_grouping'
backwards =   mystring[::-1]
print backwards

### ... or even ...
mystring  =   'coup_ate_grouping'[::-1]
print mystring

### result01 -------------------
'''
gnipuorg_eta_puoc
'''

Jawaban Lengkap

Latar Belakang

Jawaban ini diberikan untuk mengatasi masalah berikut dari @odigity:

Wow. Awalnya saya merasa ngeri dengan solusi yang diajukan Paolo, tetapi itu   mengambil kursi belakang ke kengerian yang saya rasakan saat membaca yang pertama   komentar: "Itu sangat pythonic. Kerja bagus!" Saya sangat terganggu seperti itu   komunitas yang cerdas berpikir menggunakan metode-metode rahasia semacam itu untuk sesuatu yang demikian   dasar adalah ide yang bagus. Mengapa bukan hanya s.reverse ()?

Masalah

  • Konteks
    • Python 2.x
    • Python 3.x
  • Skenario:
    • Pengembang ingin mengubah string
    • Transformasi adalah membalik urutan semua karakter

Larutan

Perangkap

  • Pengembang mungkin mengharapkan sesuatu seperti string.reverse()
  • Idiomatik asli (alias "pythonic") solusi mungkin tidak dapat dibaca oleh pengembang yang lebih baru
  • Pengembang mungkin tergoda untuk menerapkan versinya sendiri string.reverse() untuk menghindari notasi slice.
  • Output dari notasi slice mungkin bersifat kontra-intuitif dalam beberapa kasus:
    • lihat mis., example02
      • print 'coup_ate_grouping'[-4:] ## => 'ping'
      • dibandingkan dengan
      • print 'coup_ate_grouping'[-4:-1] ## => 'pin'
      • dibandingkan dengan
      • print 'coup_ate_grouping'[-1] ## => 'g'
    • hasil pengindeksan yang berbeda pada [-1] dapat membuang beberapa pengembang

Alasan

Python memiliki keadaan khusus yang harus diperhatikan: string adalah sebuah iterable mengetik.

Satu alasan untuk mengecualikan string.reverse() Metode ini memberi pengembang piton insentif untuk memanfaatkan kekuatan dari keadaan khusus ini.

Dalam istilah yang disederhanakan, ini berarti setiap karakter individu dalam string dapat dengan mudah dioperasikan sebagai bagian dari susunan berurutan elemen, seperti halnya array dalam bahasa pemrograman lainnya.

Untuk memahami cara kerjanya, meninjau contoh02 dapat memberikan ikhtisar yang bagus.

Example02

### example02 -------------------
## start (with positive integers)
print 'coup_ate_grouping'[0]  ## => 'c'
print 'coup_ate_grouping'[1]  ## => 'o' 
print 'coup_ate_grouping'[2]  ## => 'u' 

## start (with negative integers)
print 'coup_ate_grouping'[-1]  ## => 'g'
print 'coup_ate_grouping'[-2]  ## => 'n' 
print 'coup_ate_grouping'[-3]  ## => 'i' 

## start:end 
print 'coup_ate_grouping'[0:4]    ## => 'coup'    
print 'coup_ate_grouping'[4:8]    ## => '_ate'    
print 'coup_ate_grouping'[8:12]   ## => '_gro'    

## start:end 
print 'coup_ate_grouping'[-4:]    ## => 'ping' (counter-intuitive)
print 'coup_ate_grouping'[-4:-1]  ## => 'pin'
print 'coup_ate_grouping'[-4:-2]  ## => 'pi'
print 'coup_ate_grouping'[-4:-3]  ## => 'p'
print 'coup_ate_grouping'[-4:-4]  ## => ''
print 'coup_ate_grouping'[0:-1]   ## => 'coup_ate_groupin'
print 'coup_ate_grouping'[0:]     ## => 'coup_ate_grouping' (counter-intuitive)

## start:end:step (or start:end:stride)
print 'coup_ate_grouping'[-1::1]  ## => 'g'   
print 'coup_ate_grouping'[-1::-1] ## => 'gnipuorg_eta_puoc'

## combinations
print 'coup_ate_grouping'[-1::-1][-4:] ## => 'puoc'

Kesimpulan

Itu beban kognitif terkait dengan pemahaman bagaimana cara kerja notasi di python mungkin memang terlalu banyak untuk beberapa pengguna dan pengembang yang tidak ingin menghabiskan banyak waktu dalam mempelajari bahasa.

Namun demikian, setelah prinsip-prinsip dasar dipahami, kekuatan pendekatan ini atas metode manipulasi string tetap bisa sangat menguntungkan.

Bagi mereka yang berpikir sebaliknya, ada pendekatan alternatif, seperti fungsi lambda, iterator, atau deklarasi fungsi satu-off sederhana.

Jika diinginkan, pengembang dapat mengimplementasikan metode string.reverse () miliknya sendiri, namun baik untuk memahami alasan dibalik aspek python ini.

Lihat juga


33
2017-10-31 22:24



Cara yang lebih sederhana untuk melihatnya adalah:

string = 'happy'
print(string)

'senang'

string_reversed = string[-1::-1]
print(string_reversed)

'yppah'

Dalam bahasa Inggris [-1 :: - 1] dibaca sebagai:

"Mulai dari -1, jalan terus, mengambil langkah -1"


10
2018-04-01 07:49



Membalikkan string dengan python tanpa menggunakan reversed () atau [:: - 1]

def reverse(test):
    n = len(test)
    x=""
    for i in range(n-1,-1,-1):
        x += test[i]
    return x

4
2017-12-10 12:57



def reverse(input):
    return reduce(lambda x,y : y+x, input)

3
2018-06-26 04:25



menggunakan notasi slice

def rev_string(s): 
    return s[::-1]

menggunakan fungsi terbalik ()

def rev_string(s): 
    return ''.join(reversed(s))

menggunakan rekursi

def rev_string(s): 
    if len(s) == 1:
        return s

    return s[-1] + rev_string(s[:-1])

3
2018-05-20 22:24



Di sini tidak ada yang mewah:

def reverse(text):
    r_text = ''
    index = len(text) - 1

    while index >= 0:
        r_text += text[index] #string canbe concatenated
        index -= 1

    return r_text

print reverse("hello, world!")

2
2018-05-04 17:02