ฉันจะสร้างชื่อสมาชิกใน Python ได้อย่างไร?


23

ใน Python หนึ่งสามารถบันทึกไบต์โดย aliasing ฟังก์ชันที่ใช้ซ้ำ ๆ ตัวอย่างเช่น:

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
Doorknob

3
ตอนนี้การสนทนาเมตาดังกล่าวเป็นแบบกึ่งทางการ (หรืออย่างน้อยพวกเราส่วนใหญ่เห็นด้วย) ฉันได้ไปข้างหน้าและลบวิกิในโพสต์นี้
Doorknob

1
เวอร์ชันล่าสุดของคุณใช้ไม่ได้ qถูกผูกไว้กับวิธีการแทนที่ของstrอินสแตนซ์ที่เฉพาะเจาะจงนั้น นอกจากนี้โปรดจำไว้ว่าคุณสามารถเปลี่ยนถ่านได้ครั้งเดียวด้วย"Hello".replace(*"HJ")
gnibbler

คำตอบ:


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)

แน่นอนว่านี่ครอบคลุมเฉพาะกรณีหนึ่งเท่านั้น อย่างไรก็ตามรหัสกอล์ฟคือทั้งหมดที่เกี่ยวกับการค้นหากรณีพิเศษที่สามารถช่วยคุณประหยัดได้ไบต์

เป็นไปได้ที่จะเขียนฟังก์ชั่น wrapper ที่จัดการเคสทั่วไป แต่รหัสจะใหญ่เกินไปที่จะมีสถานที่ในการแข่งขันกอล์ฟโค๊ดส่วนใหญ่

คุณต้องคิดว่า "ฉันสามารถทำการเปลี่ยนแปลงนี้ได้อย่างมีประสิทธิภาพ (strokewise) กับ str.replace ฉันจะเปลี่ยนการเป็นตัวแทนภายในของโซลูชันของฉันเพื่อใช้ประโยชน์จากสิ่งนั้นได้หรือไม่ (โดยไม่ต้องสูญเสียจังหวะจำนวนมากดังนั้น


ฉันชอบคำตอบนี้เพราะมันอธิบายถึงนิสัยที่ดีเมื่อเล่นกอล์ฟและแก้ไขตัวอย่างเฉพาะที่นำเสนอ ฉันยอมรับคำตอบอื่นเนื่องจากเป็นกรณีทั่วไปมากขึ้น
Rainbolt

4

คุณอาจใช้reduceฟังก์ชั่น

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

หากคำตอบของคุณแตกต่างจากคำตอบนี้ (เท่าที่ใช้เทคนิคไม่จำเป็นต้องเขียนในรูปแบบเดียวกันแน่นอน )?
Rainbolt

1
@Rusher มันแตกต่างกัน เช่นจำนวนการเรียกใช้จะถูกกำหนดให้อย่างหนักในคำตอบที่เชื่อมโยงขณะที่ที่นี่จะได้รับเฉพาะตามความยาวของอาร์กิวเมนต์ที่สอง (ซึ่งสามารถเป็นตัววนซ้ำได้)
Howard

1

หากคุณกำลังทำหน้าที่แทนจำนวนมากคุณสามารถทำสิ่งนี้ได้:

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

ฉันหวังว่าจะได้รับคำตอบที่ไม่เฉพาะเจาะจงที่จะมาแทนที่ ฉันเพิ่งใช้มันเป็นตัวอย่าง
ฝนตก

สิ่งนี้สามารถแทนที่ได้ครั้งละ 1 ตัวอักษรเท่านั้น แต่มันสามารถแทรกการแทนที่แบบหลายถ่านได้ และนี่ไม่ใช่การเล่นกอล์ฟอย่างเต็มที่ (ลบที่ว่างหลังจากนั้น[a])
Justin

2
ไม่[a]ต้องถูกแทนที่ด้วย.get(a,a)(ไม่เช่นนั้นเราจะได้รับข้อผิดพลาด Key) และทำไมถึงมีlist(s)แทนs?
Justin

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/ คือ / แลมบ์ดานั่น! ดูคำตอบของฉัน
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.