Я рассчитал время для всех методов в текущих ответах вместе с одним дополнительным.
С помощью входной строки abc&def#ghi и замены & -> \& и # -> \# самым быстрым способом было объединить замены следующим образом: text.replace('&', '\&').replace('#', '\#').
Тайминги для каждой функции:
a) 1000000 циклов, лучшее из 3: 1,47 мкс на цикл
b) 1000000 циклов, лучшее из 3: 1,51 мкс на цикл
c) 100000 циклов, лучшее из 3: 12,3 мкс на цикл
d) 100000 циклов, лучше всего 3: 12 мкс на цикл
e) 100000 циклов, лучшее из 3: 3,27 мкс на цикл
f) 1000000 циклов, лучшее из 3: 0,817 мкс на цикл
g) 100000 циклов, лучшее из 3: 3,64 мкс на цикл
h) 1000000 циклов, лучшее из 3: 0,927 мкс на цикл
i) 1000000 циклов, лучшее из 3: 0,814 мкс на цикл
Вот функции:
defa(text): chars = "&#" for c in chars: text = text.replace(c, "\\" + c)
defb(text): for ch in ['&','#']: if ch in text: text = text.replace(ch,"\\"+ch)
import re defc(text): rx = re.compile('([&#])') text = rx.sub(r'\\\1', text)
RX = re.compile('([&#])') defd(text): text = RX.sub(r'\\\1', text)
defmk_esc(esc_chars): returnlambda s: ''.join(['\\' + c if c in esc_chars else c for c in s]) esc = mk_esc('&#') defe(text): esc(text)
deff(text): text = text.replace('&', '\&').replace('#', '\#')
defg(text): replacements = {"&": "\&", "#": "\#"} text = "".join([replacements.get(c, c) for c in text])
defh(text): text = text.replace('&', r'\&') text = text.replace('#', r'\#')
defi(text): text = text.replace('&', r'\&').replace('#', r'\#')
defg(text): replacements = { "\\": "\\\\", "`": "\`", "*": "\*", "_": "\_", "{": "\{", "}": "\}", "[": "\[", "]": "\]", "(": "\(", ")": "\)", ">": "\>", "#": "\#", "+": "\+", "-": "\-", ".": "\.", "!": "\!", "$": "\$", } text = "".join([replacements.get(c, c) for c in text])
defh(text): text = text.replace('\\', r'\\') text = text.replace('`', r'\`') text = text.replace('*', r'\*') text = text.replace('_', r'\_') text = text.replace('{', r'\{') text = text.replace('}', r'\}') text = text.replace('[', r'\[') text = text.replace(']', r'\]') text = text.replace('(', r'\(') text = text.replace(')', r'\)') text = text.replace('>', r'\>') text = text.replace('#', r'\#') text = text.replace('+', r'\+') text = text.replace('-', r'\-') text = text.replace('.', r'\.') text = text.replace('!', r'\!') text = text.replace('$', r'\$')
Here's the results for the same input string abc&def#ghi:
a) 100000 loops, best of 3: 6.72 μs per loop
b) 100000 loops, best of 3: 2.64 μs per loop
c) 100000 loops, best of 3: 11.9 μs per loop
d) 100000 loops, best of 3: 4.92 μs per loop
e) 100000 loops, best of 3: 2.96 μs per loop
f) 100000 loops, best of 3: 4.29 μs per loop
g) 100000 loops, best of 3: 4.68 μs per loop
h) 100000 loops, best of 3: 4.73 μs per loop
i) 100000 loops, best of 3: 4.24 μs per loop
И более длинной входной строкой (## *Something* and [another] thing in a longer sentence with {more} things to replace$):
a) 100000 циклов, лучшее из 3: 7,59 мкс на цикл
b) 100000 циклов, лучшее из 3: 6,54 мкс на цикл
c) 100000 циклов, лучшее из 3: 16,9 мкс на цикл
d) 100000 циклов, лучшее из 3: 7,29 мкс на цикл
e) 100000 циклов, лучшее из 3: 12,2 мкс на цикл
f) 100000 циклов, лучшее из 3: 5,38 мкс на цикл
g) 10000 циклов, лучшее из 3: 21,7 мкс на цикл
h) 100000 циклов, лучшее из 3: 5,7 мкс на цикл
i) 100000 циклов, лучшее из 3: 5,13 мкс на цикл
Добавляем пару вариантов:
defab(text): for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']: text = text.replace(ch,"\\"+ch)
defba(text): chars = "\\`*_{}[]()>#+-.!$" for c in chars: if c in text: text = text.replace(c, "\\" + c)
С более коротким вводом:
ab) 100000 циклов, лучшее из 3: 7,05 мкс на цикл
ba) 100000 циклов, лучшее из 3: 2,4 мкс на цикл
С более длинным вводом:
ab) 100000 циклов, лучшее из 3: 7,71 мкс на цикл
ba) 100000 циклов, лучшее из 3: 6,08 мкс на цикл
Итак, я собираюсь использовать ba для удобства чтения и скорости.
Дополнение
Согласно подсказкам в комментариях, одно отличие между ab и ba заключается в if c in text: проверке. Давайте протестируем их еще на двух вариантах:
defab_with_check(text): for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']: if ch in text: text = text.replace(ch,"\\"+ch)
defba_without_check(text): chars = "\\`*_{}[]()>#+-.!$" for c in chars: text = text.replace(c, "\\" + c)
Количество раз в мкс за цикл на Python 2.7.14 и 3.6.3 и на компьютере, отличном от предыдущего набора, поэтому напрямую сравнивать нельзя.
Те, у кого есть проверка, работают в 4 раза быстрее, чем те, у кого ее нет
ab_with_check немного лидирует на Python 3, но ba (с проверкой) имеет большее преимущество на Python 2
Однако самый важный урок здесь заключается в том, что Python 3 работает в 3 раза быстрее, чем Python 2! Нет большой разницы между самым медленным в Python 3 и самым быстрым в Python 2!