Làm cách nào để bí danh các hàm thành viên trong Python?


23

Trong Python, người ta có thể lưu byte bằng cách đặt các hàm bí danh được sử dụng nhiều lần. Ví dụ:

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

Tuy nhiên, khi các chức năng là các chức năng thành viên với nhau, tôi không biết cách đặt bí danh cho chúng theo cách cho phép xâu chuỗi. Ví dụ:

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

Rõ ràng, những gì tôi đang cố gắng làm là không hợp lệ. Và đây cũng không phải là:

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

Có một cách khác để bí danh các chức năng thành viên và chức năng xâu chuỗi để lưu các ký tự?


Xác định lớp của riêng bạn, với phương thức của nó qcó nghĩa là gì replacetrong lớp bạn sử dụng.
Ypnypn

3
Tôi rất vui vì điều này đã không bị hạ cấp :)
TheDoctor

2
Bây giờ tôi đã không thích tất cả các câu trả lời, nhưng chúng tôi chưa đạt được sự đồng thuận đủ mạnh để kêu gọi giải quyết vấn đề này và các câu hỏi tương tự. Xem thêm: meta.codegolf.stackexchange.com/q/1555/3808
Doorknob

3
Bây giờ, cuộc thảo luận meta đã nói ở trên là bán chính thức (hoặc ít nhất là hầu hết chúng ta đồng ý), tôi đã tiếp tục và xóa wiki trên bài đăng này.
Doorknob

1
Phiên bản cuối cùng của bạn không hoạt động. qbị ràng buộc với phương thức thay thế của strtrường hợp cụ thể đó. Ngoài ra, hãy nhớ rằng bạn có thể thực hiện thay thế char duy nhất với"Hello".replace(*"HJ")
gnibbler

Câu trả lời:


28

Không vấn đề gì! Bạn có thể bí danh một phương thức, nhưng bạn phải biết cách sử dụng nó:

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

Điều quan trọng là bạn phải vượt qua selfmột cách rõ ràng, vì bí danh là một loại hàm có thêm một đối số có self:

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

3
Làm thế nào tôi không nhìn thấy điều này trước đây?
Rainbolt

6

Xác định lớp của riêng bạn, với một tên phương thức ngắn hơn.

Ví dụ, nếu bạn đang sử dụng phương thức replace()thuộc về Stringlớp, bạn có thể làm cho lớp của riêng bạn Scó một phương thức được gọi là phương thức qtương tự.

Đây là một cách thực hiện:

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

Đây là một thực hiện tốt hơn nhiều:

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

Sử dụng nó như vậy:

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

5

Dù sao đây cũng là một vài ký tự

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

thậm chí ngắn hơn cho một số lượng nhỏ thay thế là

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

Tất nhiên điều này chỉ bao gồm một trường hợp cụ thể. Tuy nhiên, mã golf là tất cả về việc tìm kiếm những trường hợp đặc biệt có thể giúp bạn tiết kiệm byte.

Có thể viết một hàm bao bọc xử lý trường hợp chung, nhưng mã sẽ quá lớn để có chỗ trong hầu hết các thử thách golf mã.

Thay vào đó, bạn cần phải suy nghĩ "Tôi có thể thực hiện chuyển đổi này một cách hiệu quả (theo chiều dọc) với str.replace. Tôi có thể thay đổi cách biểu diễn bên trong của giải pháp của mình để tận dụng lợi thế đó không (không lãng phí quá nhiều nét để phủ nhận lợi thế)"


Tôi thích câu trả lời này vì nó mô tả những thói quen tốt khi chơi golf và chắc chắn giải quyết được ví dụ cụ thể được trình bày. Tôi chấp nhận một câu trả lời khác vì nó được áp dụng cho trường hợp tổng quát hơn.
Rainbolt

4

Bạn có thể sử dụng reducechức năng.

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

Nếu câu trả lời của bạn khác với câu trả lời này (theo như kỹ thuật được sử dụng, không nhất thiết phải được viết dưới dạng chính xác )?
Rainbolt

1
@Raser Nó khác. Ví dụ, số lượng các yêu cầu được mã hóa cứng trong câu trả lời được liên kết trong khi ở đây nó chỉ được đưa ra bởi độ dài của đối số thứ hai (có thể là bất kỳ trình lặp nào).
Howard

1

Nếu bạn đang thực hiện nhiều thay thế, bạn có thể làm điều này:

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

Tôi đã hy vọng cho một câu trả lời không cụ thể để thay thế. Tôi chỉ sử dụng nó như một ví dụ.
Rainbolt

Điều này chỉ có thể thay thế 1 char mỗi lần, nhưng nó có thể chèn thay thế nhiều char. Và điều này không hoàn toàn được đánh gôn (loại bỏ khoảng trống sau [a])
Justin

2
Không phải [a]thay thế bằng .get(a,a)(nếu không, chúng tôi nhận được một số lỗi chính)? Và tại sao phải list(s)thay thế s?
Justin

1

Làm thế nào về việc xác định một hàm 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
Không cần: str.replace/ là / lambda! Xem câu trả lời của tôi.
MtnViewMark

1

Nếu sự thay thế của bạn không cần phải bị xiềng xích, bạn có thể sử dụng 'str.translate'. Các con số là thứ tự ASCII. Sử dụng nó theo cách này đòi hỏi Python 3:

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

Dùng thử trực tuyến

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.