Pythonでメンバー関数をエイリアスするにはどうすればよいですか?


23

Pythonでは、繰り返し使用される関数をエイリアスすることでバイトを節約できます。例えば:

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

ただし、関数が一緒にメンバー関数である場合、チェーンを可能にする方法でそれらをエイリアスする方法がわかりません。例えば:

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

明らかに、私がやろうとしていることは無効です。そして、これもどちらでもありません:

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

メンバー関数とチェーン関数をエイリアスして文字を保存する別の方法はありますか?


その方法で、独自のクラスを定義してq何の意味replaceあなたの使用してクラスの手段。
Ypnypn

3
これがダウン投票されなかったことをうれしく思います:)
TheDoctor

2
私は今のところすべての回答のウィキを解除しましたが、この質問と同様の質問のウィキ解除を求めるほど十分に強力なコンセンサスに達していません。参照:meta.codegolf.stackexchange.com/q/1555/3808
ドアノブ

3
前述のメタディスカッションは半公式(または少なくとも私たちのほとんどが同意する)になったので、先に進み、この投稿のwikiを削除しました。
ドアノブ

1
最後のバージョンは機能しません。qその特定のstrインスタンスのreplaceメソッドにバインドされます。また、"Hello".replace(*"HJ")
次のコマンドで

回答:


28

問題ありません!メソッドのエイリアスを作成できますが、使用方法を知っておく必要があります。

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

重要なのはself、エイリアスは次の引数をとる一種の関数であるため、明示的に渡す必要があるということですself

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

3
これを前に見なかったのはどうしてですか?
レインボルト

6

短いメソッド名で独自のクラスを定義します。

たとえばreplace()Stringクラスに属するメソッドを使用している場合、同じことを行うSメソッドを独自のクラスに持たせることができますq

実装の1つを次に示します。

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

はるかに優れた実装を次に示します。

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

次のように使用します。

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

5

とにかくこれは数文字短い

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

少数の交換でさらに短くなります

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

もちろん、これは1つの特定のケースのみを対象としています。ただし、コードゴルフでは、バイトを節約できる特別なケースを見つけることが重要です。

一般的なケースを処理するラッパー関数を作成することは可能ですが、ほとんどのゴルフの課題に対処するにはコードが大きすぎます。

代わりに、「str.replaceを使用してこの変換を効率的に(ストロークごとに)実行できます。それを活用するためにソリューションの内部表現をシフトできますか?(多くのストロークを無駄にせずに利点を無効にできます)」


ゴルフの際の良い習慣を説明し、提示された特定の例を確実に解決するため、この回答が好きです。より一般的なケースに適用できるため、別の回答を受け入れました。
レインボルト

4

このreduce機能を使用できます。

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

あなたの答えがこの答えと異なる場合(使用される技術に関しては、必ずしも正確に同じ形式で書かれているわけではありません)?
レインボルト14年

1
@Rusher違います。たとえば、呼び出しの数はリンクされた回答にハードコードされていますが、ここでは2番目の引数の長さ(任意のイテレータ)によってのみ指定されます。
ハワード

1

多くの置換を行っている場合、これを行うことができます:

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

私は、置き換えるのが具体的ではない答えを望んでいました。例としてそれを使用しました。
レインボルト

これは一度に1文字しか置換できませんが、複数文字の置換を挿入できます。そして、これは完全にゴルフされていません(後にスペースを削除[a]
ジャスティン

2
[a]置き換える必要はありませんか.get(a,a)(そうでなければ、キーエラーが発生します)?そして、なぜのlist(s)代わりにs
ジャスティン

1

ラムダ関数を定義するのはどうですか?

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

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

1
必要ありません:str.replace/ is /そのラムダ!私の答えをご覧ください。
MtnViewMark

1

置換を連鎖させる必要がない場合は、 `str.translate 'を使用できます。数字はASCII序数です。この方法で使用するには、Python 3が必要です。

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

オンラインで試す

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.