Best way to replace multiple characters in a string?

前端 未结 14 1798
遇见更好的自我
遇见更好的自我 2020-11-22 11:15

I need to replace some characters as follows: &\\&, #\\#, ...

I coded as follows, but I guess there

14条回答
  •  花落未央
    2020-11-22 11:30

    For Python 3.8 and above, one can use assignment expressions

    (text := text.replace(s, f"\\{i}") for s in "&#" if s in text)
    

    Although, I am quite unsure if this would be considered "appropriate use" of assignment expressions as described in PEP 572, but looks clean and reads quite well (to my eyes). This would be "appropriate" if you wanted all intermediate strings as well. For example, (removing all lowercase vowels):

    text = "Lorem ipsum dolor sit amet"
    intermediates = [text := text.replace(i, "") for i in "aeiou" if i in text]
    
    ['Lorem ipsum dolor sit met',
     'Lorm ipsum dolor sit mt',
     'Lorm psum dolor st mt',
     'Lrm psum dlr st mt',
     'Lrm psm dlr st mt']
    

    On the plus side, it does seem (unexpectedly?) faster than some of the faster methods in the accepted answer, and seems to perform nicely with both increasing strings length and an increasing number of substitutions.

    The code for the above comparison is below. I am using random strings to make my life a bit simpler, and the characters to replace are chosen randomly from the string itself. (Note: I am using ipython's %timeit magic here, so run this in ipython/jupyter).

    import random, string
    
    def make_txt(length):
        "makes a random string of a given length"
        return "".join(random.choices(string.printable, k=length))
    
    def get_substring(s, num):
        "gets a substring"
        return "".join(random.choices(s, k=num))
    
    def a(text, replace): # one of the better performing approaches from the accepted answer
        for i in replace:
            if i in text:
                 text = text.replace(i, "")
    
    def b(text, replace):
        _ = (text := text.replace(i, "") for i in replace if i in text) 
    
    
    def compare(strlen, replace_length):
        "use ipython / jupyter for the %timeit functionality"
    
        times_a, times_b = [], []
    
        for i in range(*strlen):
            el = make_txt(i)
            et = get_substring(el, replace_length)
    
            res_a = %timeit -n 1000 -o a(el, et) # ipython magic
    
            el = make_txt(i)
            et = get_substring(el, replace_length)
            
            res_b = %timeit -n 1000 -o b(el, et) # ipython magic
    
            times_a.append(res_a.average * 1e6)
            times_b.append(res_b.average * 1e6)
            
        return times_a, times_b
    
    #----run
    t2 = compare((2*2, 1000, 50), 2)
    t10 = compare((2*10, 1000, 50), 10)
    

提交回复
热议问题