Python'da üye işlevlerini nasıl isimlendiririm?


23

Python'da, defalarca kullanılan takma işlevler kullanılarak baytlar kurtarılabilir. Örneğin:

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

Bununla birlikte, işlevler üye işlevler olduğunda, zincirlemeyi mümkün kılacak şekilde nasıl alias yapmaları gerektiğini bilmiyorum. Örneğin:

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

Açıkçası, yapmaya çalıştığım şey geçerli değil. Ve bu da:

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

Takma üye işlevlerinin ve karakterleri kaydeden zincirleme işlevlerin başka bir yolu var mı?


Kendi sınıfınızı, kullandığınız sınıfta qne replaceanlama geldiğini gösteren yöntemi ile tanımlayın .
Ypnypn

3
Bu :) downvoted edilmemiştir sevindim
TheDoctor

2
Şimdilik tüm cevapları küfür ettim, ancak bu ve benzeri soruların çözülmesi için çağrı yapacak kadar güçlü bir fikir birliğine varmadık. Ayrıca bakınız: meta.codegolf.stackexchange.com/q/1555/3808
Doorknob

3
Şimdi anılan meta tartışmasının yarı-resmi (ya da en azından çoğumuzun kabul ettiği) olduğu için, bu yazıdaki wikiyi kaldırdım.
Doorknob

1
Son sürümün çalışmıyor. qsöz konusu vakanın değiştirme yöntemine bağlı str. Ayrıca, char ile tek char değişikliklerini yapabileceğinizi unutmayın"Hello".replace(*"HJ")
gnibbler

Yanıtlar:


28

Problem yok! Bir yöntemi takma adlandırabilirsiniz, ancak nasıl kullanılacağını bilmek zorundasınız:

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

Anahtar, selfaçık bir şekilde iletmeniz gerektiğidir, çünkü takma ad, aşağıdakileri ekleyen bir argüman alan bir tür işlevdir self:

>>> type(r)
<type 'method_descriptor'>

3
Bunu daha önce nasıl görmedim?
Rainbolt

6

Daha kısa bir yöntem adıyla kendi sınıfınızı tanımlayın.

Örneğin replace(), Stringsınıfa ait yöntemi kullanıyorsanız, kendi sınıfınızı aynı şeyi yapan Sbir yöntemle yapabilirsiniz q.

İşte bir uygulama:

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

İşte çok daha iyi bir uygulama:

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

Öyle kullanın:

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

5

Bu yine de birkaç karakterden kısa

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

az sayıda değiştirme için daha kısa

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

Elbette bu sadece belirli bir durumu kapsar. Ancak kod golf, sizi bayt kurtarabilecek özel durumları bulmakla ilgili.

Genel durumu ele alan bir sarmalayıcı işlevi yazmak mümkündür, ancak kod, çoğu kod golf mücadelesinde yer almak için çok büyük olacaktır.

Bunun yerine "str.replace ile bu dönüşümü verimli bir şekilde yapabilirim (strokewise) yapabilirim. Bundan yararlanmak için çözümümün içsel gösterimini değiştirebilir miyim? (Avantajı yok etmek için çok fazla vuruş yapmadan)"


Bu cevabı sevdim çünkü golf oynamak için iyi alışkanlıklar açıklar ve sunulan özel örneği kesinlikle çözer. Başka bir cevabı kabul ettim çünkü daha genel davaya uygulanabilir.
Rainbolt

4

reduceFonksiyonu kullanabilirsiniz .

reduce(lambda s,(a,b):s.replace(a,b),[('H','J'),('e','i'),('l','m'),('o','y')],'Hello')

Dan Cevabınız farklı ise bu cevap (kadarıyla tekniği kullanıldığı gibi, ille de yazılı değil tam aynı formda)?
Rainbolt

1
@Rusher Farklı. Örneğin, çağrı sayısı bağlantılı cevapta kodlanmıştır, ancak burada sadece ikinci argümanın uzunluğu (herhangi bir yineleyici olabilir) tarafından verilmektedir.
Howard

1

Eğer bir yapıyorsanız çok cümledeki nedeniyle, bu yapabilirdi:

s=''.join({'H':'J','e':'i','l':'m','o':'y'}[a] for a in list(s))

Değiştirilmesi kesin olmayan bir cevap bekliyordum. Bunu sadece örnek olarak kullandım.
Rainbolt

Bu, bir seferde yalnızca 1 karakter değiştirebilir, ancak çok karakterli değiştirmeler ekleyebilir. Ve bu tamamen golf değil (sonra boşluğu kaldırmak [a])
Justin,

2
Does not [a]ile değiştirilmesi gerekir .get(a,a)(aksi halde bazı Anahtar Hata şeyi)? Ve neden list(s)yerine s?
Justin,

1

Bir lambda fonksiyonunu tanımlamaya ne dersiniz?

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

s=r(r(r(r(s,'H','J'),'e','i'),'l','m'),'o','y')

1
Gerek yok: str.replace/ is / o lambda! Cevabımı gör.
MtnViewMark

1

Değiştirmelerinizin zincirlenmesi gerekmiyorsa, `str.translate 'komutunu kullanabilirsiniz. Sayılar ASCII sıralarıdır. Bu şekilde kullanmak Python 3 gerektirir:

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

Çevrimiçi deneyin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.