2009-04-18 40 views
22

Có cách nào ngắn hơn để viết mã sau đây không?Danh sách các thay thế chuỗi trong Python

my_string = my_string.replace('A', '1') 
my_string = my_string.replace('B', '2') 
my_string = my_string.replace('C', '3') 
my_string = my_string.replace('D', '4') 
my_string = my_string.replace('E', '5') 

Lưu ý rằng tôi không cần những giá trị chính xác được thay thế; Tôi chỉ đơn giản là tìm kiếm một cách để biến dòng 5 + vào ít hơn 5

Trả lời

44

Trông giống như một cơ hội tốt để sử dụng một vòng lặp:

mapping = { 'A':'1', 'B':'2', 'C':'3', 'D':'4', 'E':'5'} 
for k, v in mapping.iteritems(): 
    my_string = my_string.replace(k, v) 

Một cách tiếp cận nhanh hơn nếu bạn không nhớ các dấu ngoặc đơn sẽ là:

mapping = [ ('A', '1'), ('B', '2'), ('C', '3'), ('D', '4'), ('E', '5') ] 
for k, v in mapping: 
    my_string = my_string.replace(k, v) 
+1

Thật kỳ lạ; đó là cách tôi viết nó, bởi vì vấn đề là tất cả về lập bản đồ từ một nhân vật khác. Nhưng thực sự, bạn không sử dụng dict như một dict; bạn đang sử dụng nó như một danh sách các bộ dữ liệu. Vậy tại sao không viết một danh sách các bộ dữ liệu ngay từ đầu? –

+0

Chắc chắn một danh sách các bộ dữ liệu cũng sẽ hoạt động (và nhanh hơn). Tôi sẽ chỉnh sửa câu trả lời để bao gồm tùy chọn đó. –

+2

Nếu bạn sẽ có ánh xạ này {'A': '1', '1': 'A'} có thể kết quả sẽ không giống như mong đợi – muni764

6
replaceDict = {'A':'1','B':'2','C':'3','D':'4','E':'5'}  
for key, replacement in replaceDict.items(): 
    my_string = my_string.replace(key, replacement)
15

Cũng xem xét str.translate(). Nó thay thế các ký tự theo một ánh xạ mà bạn cung cấp cho các chuỗi Unicode, hoặc nói cách khác là phải thay đổi từng ký tự từ chr (0) thành chr (255) bằng.

35

Bạn có thể dễ dàng sử dụng string.maketrans() để tạo ra các chuỗi bản đồ để vượt qua để str.translate():

import string 
trans = string.maketrans("ABCDE","12345") 
my_string = my_string.translate(trans) 
+2

điều này là tốt đẹp, nhưng không hoạt động trong trường hợp các mẫu nhiều ký tự hoặc thay thế –

+0

Đúng. Tôi giả định từ câu hỏi rằng đó là thay thế dựa trên nhân vật. –

+0

tiết kiệm cho tôi một câu hỏi, thx – ohho

10

Nếu bạn muốn để có được những câu trả lời sai, chậm rãi, sau đó sử dụng String.Replace trong một vòng lặp. (Mặc dù nó không làm việc trong trường hợp này không có sự chồng chéo giữa các mẫu và thay thế.)

Đối với trường hợp chung với chồng chéo có thể hoặc một chuỗi vấn đề lâu dài, sử dụng re.sub:

import re 

def multisub(subs, subject): 
    "Simultaneously perform all substitutions on the subject string." 
    pattern = '|'.join('(%s)' % re.escape(p) for p, s in subs) 
    substs = [s for p, s in subs] 
    replace = lambda m: substs[m.lastindex - 1] 
    return re.sub(pattern, replace, subject) 

>>> multisub([('hi', 'bye'), ('bye', 'hi')], 'hi and bye') 
'bye and hi' 

Đối với đặc biệt trường hợp các mẫu 1 ký tự và các thay thế 1 hoặc 0 ký tự, hãy sử dụng string.maketrans.

+0

+1 về phương pháp sử dụng re.sub, -1 để nói rằng 'string.replace' đưa ra câu trả lời sai, vì nó không rõ ràng chính xác những gì * nên * xảy ra cho các kết quả trùng lặp trùng lặp. Vì vậy, net 0 :) –

+1

str.replace có thể đưa ra một câu trả lời cho là sai. Đối với các giải pháp dựa trên từ điển, hãy xem chuỗi "wow" và bảng dịch {'w': 'foo', 'o': 'bar'}. Tùy thuộc vào thứ tự mà dict lặp lại, bạn có thể kết thúc với các kết quả khác nhau: "fbarbarbarfbarbar" hoặc "foobarfoo". Một hàm cho đầu ra khác nhau cho đầu vào bằng nhau được cho là bị hỏng. – Miles

+0

Miles, vâng, đó là loại vấn đề tôi muốn nói.Bạn cũng có thể chạy vào các chồng chéo trong các phím một mình, như 'hello' và 'hell'. –

1

Một cách tôi làm là với một mảng được liên kết (từ điển). Dưới đây là ví dụ về các thay thế tôi sử dụng khi nhận tệp sẵn sàng triển khai trong LaTeX bằng cách sử dụng cụm từ thông dụng.

import re 
    def escapeTexString(string): # Returns TeX-friendly string 
    rep = { # define desired replacements in this dictionary (mapping) 
     '&': '\\&', 
     '%': '\\%', 
     '#': '\\#', 
     '_': '\\_', 
     '{': '\\{', # REGEX Special 
     '}': '\\}', # REGEX Special 
     '~': '\\char"007E{}', # LaTeX Special 
     '$': '\\$', # REGEX Special 
     '\\': '\\char"005C{}', # REGEX/LaTeX Special 
     '^': '\\char"005E{}', # REGEX/LaTeX Special 
     '"': '\\char"FF02{}' 
     } 
    # use these two lines to do the replacement (could be shortened to one line) 
    pattern = re.compile("|".join(map(re.escape,rep.keys()))) # Create single pattern object (key to simultaneous replacement) 
    new_string = pattern.sub(lambda match: rep[match.group(0)], string) 
    return new_string 
Các vấn đề liên quan