如何在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
我很高兴这没有被
否决

2
我目前尚未取消所有维基百科的答案,但是我们尚未达成足够强烈的共识,要求取消对该问题和类似问题的维基百科。另请参阅:meta.codegolf.stackexchange.com/q/1555/3808
门把手

3
既然前面提到的元讨论是半官方的(或者至少我们中的大多数人都同意),我已经继续并删除了这篇文章上的Wiki。
门把手

1
您的上一个版本不起作用。q绑定到该特定str实例的replace方法。另外,请记住,您可以使用"Hello".replace(*"HJ")
gnibbler

Answers:


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
我怎么没看到这个?
Rainbolt

6

使用较短的方法名称定义您自己的类。

例如,如果您使用的是replace()属于String该类的方法,则可以使自己的类S具有一个称为的方法q,该方法执行相同的操作。

这是一个实现:

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)

当然,这仅涉及一种特殊情况。但是,代码高尔夫只不过是寻找可以节省字节数的特殊情况。

可以编写一个处理一般情况的包装函数,但是该代码太大了,无法在大多数代码挑战中占据一席之地。

相反,您需要考虑“我可以使用str.replace高效地(按笔画方向)进行此转换。我可以改变解决方案的内部表示以利用它吗?(不会浪费很多笔画来抵消优势)”


我喜欢这个答案,因为它描述了打高尔夫球时的良好习惯,并且肯定解决了所提出的具体示例。我接受了另一个答案,因为它适用于更一般的情况。
Rainbolt 2014年

4

您可以使用该reduce功能。

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

如果您的答案与答案不同(就所使用的技术而言,不一定以完全相同的形式编写)?
Rainbolt 2014年

1
@Rusher是不同的。例如,调用次数在链接的答案中是硬编码的,而此处的调用次数仅由第二个参数的长度(可以是任何迭代器)的长度给出。
霍华德

1

如果您要进行大量替换,则可以执行以下操作:

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

我希望得到一个并非专门替换的答案。我只是以此为例。
Rainbolt 2014年

一次只能替换1个字符,但可以插入多字符替换。并且这还没有完全打高尔夫球(请在之后删除空间[a]
贾斯汀

2
不将[a]不得不被替换.get(a,a)(否则,我们得到了一些重要的东西错误)?而为什么要list(s)代替s呢?
贾斯汀

1

定义lambda函数如何?

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 /那个lambda!看我的答案。
MtnViewMark

1

如果不需要链接替换项,则可以使用“ str.translate”。数字是ASCII序数。以这种方式使用它需要Python 3:

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

在线尝试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.