Bagaimana cara saya alias fungsi anggota di Python?

23

Dalam Python, seseorang dapat menyimpan byte dengan aliasing fungsi yang digunakan berulang kali. Sebagai contoh:

r=range
a=r(100)
b=r(200)
c=r(300)

Namun, ketika fungsi-fungsi tersebut adalah fungsi anggota bersama-sama, saya tidak tahu cara mengatasinya dengan cara yang memungkinkan perangkaian. Sebagai contoh:

s='Hello'

// Plain code
s=s.replace('H','J').replace('e','i').replace('l','m').replace('o','y')

// What I am trying to do
q=replace
s=s.q('H','J').q('e','i').q('l','m').q('o','y')

Jelas, apa yang saya coba lakukan tidak valid. Dan ini juga tidak:

q=s.replace
s=q('H','J') // Replaces the 'H' in 'Hello'
s=q('e','i') // Replaces the 'e' in 'Hello'... and the J is gone.
s=q('l','m')
s=q('o','y')

Apakah ada cara lain untuk fungsi alias anggota dan fungsi dirantai yang menyimpan karakter?

Rainbolt
sumber
Tentukan kelas Anda sendiri, dengan metodenya yang qberarti apa replaceartinya di kelas yang Anda gunakan.
Ypnypn
3
Saya senang ini belum diturunkan :)
TheDoctor
2
Saya telah menghapus semua jawaban untuk saat ini, tetapi kami belum mencapai konsensus yang cukup kuat untuk menyerukan untuk tidak mengaitkan ini dan pertanyaan serupa. Lihat juga: meta.codegolf.stackexchange.com/q/1555/3808
Doorknob
3
Sekarang setelah diskusi meta yang disebutkan di atas bersifat semi-resmi (atau setidaknya sebagian besar dari kita setuju), saya telah melanjutkan dan menghapus wiki pada pos ini.
Gagang Pintu
1
Versi terakhir Anda tidak berfungsi. qterikat pada metode ganti strcontoh khusus itu . Juga, ingat Anda dapat melakukan penggantian char tunggal dengan"Hello".replace(*"HJ")
gnibbler

Jawaban:

28

Tidak masalah! Anda dapat menggunakan alias metode, tetapi Anda harus tahu cara menggunakannya:

>>> r=str.replace
>>> a='hello'
>>> r(r(r(r(a,'h','j'),'e','i'),'l','m'),'o','y')
'jimmy'

Kuncinya adalah Anda harus lulus selfsecara eksplisit, karena alias adalah jenis fungsi yang membutuhkan argumen tambahan yang membutuhkan self:

>>> type(r)
<type 'method_descriptor'>
MtnViewMark
sumber
3
Bagaimana saya tidak melihat ini sebelumnya?
Rainbolt
6

Tentukan kelas Anda sendiri, dengan nama metode yang lebih pendek.

Misalnya, jika Anda menggunakan metode replace()milik Stringkelas, Anda bisa membuat kelas Anda sendiri Smemiliki metode yang disebut qyang melakukan hal yang sama.

Berikut ini satu implementasinya:

class m(str):
 def q(a,b,c):return m(a.replace(b,c))

Berikut ini adalah implementasi yang jauh lebih baik:

class m(str):q=lambda a,b,c:m(a.replace(b,c))

Gunakan seperti ini:

s="Hello"
s=m(s).q('H','J').q('e','i').q('l','m').q('o','y')
Ypnypn
sumber
5

Ini beberapa karakter lebih pendek

j=iter('HJeilmoy')
for i in j:s=s.replace(i,next(j))

bahkan lebih pendek untuk sejumlah kecil penggantian

for i in['HJ','ei','lm','oy']:s=s.replace(*i)

tentu saja ini hanya mencakup satu kasus tertentu. Namun golf kode adalah semua tentang menemukan kasus-kasus khusus yang dapat menghemat byte.

Dimungkinkan untuk menulis fungsi pembungkus yang menangani kasus umum, tetapi kode akan terlalu besar untuk mendapat tempat di sebagian besar tantangan kode golf.

Anda malah perlu berpikir, "Saya bisa melakukan transformasi ini secara efisien (dengan strok) dengan str.replace. Dapatkah saya menggeser representasi internal dari solusi saya untuk mengambil keuntungan dari itu? (Tanpa membuang begitu banyak stroke untuk meniadakan keuntungan)"

gnibbler
sumber
Saya memang suka jawaban ini karena ini menggambarkan kebiasaan baik ketika bermain golf dan pasti memecahkan contoh spesifik yang disajikan. Saya menerima jawaban lain karena ini berlaku untuk kasus yang lebih umum.
Rainbolt
4

Anda dapat menggunakan reducefungsi ini.

reduce(lambda s,(a,b):s.replace(a,b),[('H','J'),('e','i'),('l','m'),('o','y')],'Hello')
Howard
sumber
Jika jawaban Anda berbeda dari jawaban ini (sejauh teknik yang digunakan, belum tentu ditulis dalam bentuk yang sama persis )?
Rainbolt
1
@Rusher Ini berbeda. Misalnya, jumlah pemanggilan tertulis dalam bentuk hard-code dalam jawaban yang ditautkan sementara di sini hanya diberikan oleh panjangnya argumen kedua (yang bisa berupa iterator apa saja).
Howard
1

Jika Anda melakukan banyak penggantian, Anda bisa melakukan ini:

s=''.join({'H':'J','e':'i','l':'m','o':'y'}[a] for a in list(s))
Dokter
sumber
Saya berharap jawaban yang tidak spesifik untuk diganti. Saya hanya menggunakan itu sebagai contoh.
Rainbolt
Ini hanya bisa mengganti 1 karakter sekaligus, tetapi bisa memasukkan penggantian multi karakter. Dan ini tidak sepenuhnya golf (hapus spasi setelah [a])
Justin
2
Bukankah [a]harus diganti dengan .get(a,a)(jika tidak, kita mendapatkan beberapa Key Error)? Dan mengapa list(s)bukannya s?
Justin
1

Bagaimana dengan mendefinisikan fungsi lambda?

r=lambda s,a,b:s.replace(a,b)

s=r(r(r(r(s,'H','J'),'e','i'),'l','m'),'o','y')
Justin
sumber
1
Tidak perlu: str.replace/ itu / lambda itu! Lihat jawaban saya.
MtnViewMark
1

Jika penggantian Anda tidak perlu dirantai, Anda dapat menggunakan `str.translate '. Angka-angkanya adalah tata cara ASCII. Menggunakannya dengan cara ini membutuhkan Python 3:

print("Hello".translate({72:74,101:105,108:109,111:121}))

Cobalah online

mbomb007
sumber