답변:
나는 현재 답변의 모든 방법을 하나 더 추가했습니다.
abc&def#ghi
&-> \ & 및 #-> \ # 의 입력 문자열을 사용 하여 대체하는 가장 빠른 방법은 다음과 같이 대체를 연결하는 것 text.replace('&', '\&').replace('#', '\#')
입니다.
각 기능의 타이밍 :
기능은 다음과 같습니다.
def a(text):
chars = "&#"
for c in chars:
text = text.replace(c, "\\" + c)
def b(text):
for ch in ['&','#']:
if ch in text:
text = text.replace(ch,"\\"+ch)
import re
def c(text):
rx = re.compile('([&#])')
text = rx.sub(r'\\\1', text)
RX = re.compile('([&#])')
def d(text):
text = RX.sub(r'\\\1', text)
def mk_esc(esc_chars):
return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('&#')
def e(text):
esc(text)
def f(text):
text = text.replace('&', '\&').replace('#', '\#')
def g(text):
replacements = {"&": "\&", "#": "\#"}
text = "".join([replacements.get(c, c) for c in text])
def h(text):
text = text.replace('&', r'\&')
text = text.replace('#', r'\#')
def i(text):
text = text.replace('&', r'\&').replace('#', r'\#')
이 같은 시간 :
python -mtimeit -s"import time_functions" "time_functions.a('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.b('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.c('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.d('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.e('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.f('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.g('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.h('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.i('abc&def#ghi')"
다음은 동일하지만 이스케이프 할 문자가 더 많은 유사한 코드입니다 (\`* _ {}> # +-.! $) :
def a(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
text = text.replace(c, "\\" + c)
def b(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
if ch in text:
text = text.replace(ch,"\\"+ch)
import re
def c(text):
rx = re.compile('([&#])')
text = rx.sub(r'\\\1', text)
RX = re.compile('([\\`*_{}[]()>#+-.!$])')
def d(text):
text = RX.sub(r'\\\1', text)
def mk_esc(esc_chars):
return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('\\`*_{}[]()>#+-.!$')
def e(text):
esc(text)
def f(text):
text = text.replace('\\', '\\\\').replace('`', '\`').replace('*', '\*').replace('_', '\_').replace('{', '\{').replace('}', '\}').replace('[', '\[').replace(']', '\]').replace('(', '\(').replace(')', '\)').replace('>', '\>').replace('#', '\#').replace('+', '\+').replace('-', '\-').replace('.', '\.').replace('!', '\!').replace('$', '\$')
def g(text):
replacements = {
"\\": "\\\\",
"`": "\`",
"*": "\*",
"_": "\_",
"{": "\{",
"}": "\}",
"[": "\[",
"]": "\]",
"(": "\(",
")": "\)",
">": "\>",
"#": "\#",
"+": "\+",
"-": "\-",
".": "\.",
"!": "\!",
"$": "\$",
}
text = "".join([replacements.get(c, c) for c in text])
def h(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'\$')
def i(text):
text = text.replace('\\', r'\\').replace('`', r'\`').replace('*', r'\*').replace('_', r'\_').replace('{', r'\{').replace('}', r'\}').replace('[', r'\[').replace(']', r'\]').replace('(', r'\(').replace(')', r'\)').replace('>', r'\>').replace('#', r'\#').replace('+', r'\+').replace('-', r'\-').replace('.', r'\.').replace('!', r'\!').replace('$', r'\$')
동일한 입력 문자열에 대한 결과는 다음과 같습니다 abc&def#ghi
.
그리고 더 긴 입력 문자열 ( ## *Something* and [another] thing in a longer sentence with {more} things to replace$
)
몇 가지 변형 추가 :
def ab(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
text = text.replace(ch,"\\"+ch)
def ba(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
if c in text:
text = text.replace(c, "\\" + c)
더 짧은 입력으로 :
더 긴 입력으로 :
ba
가독성과 속도 를 위해 사용하겠습니다 .
주석에서 haccks에 의해 프롬프트되며 , 확인 ab
과 확인의 차이점은 하나 입니다. 두 가지 변형에 대해 테스트 해 보겠습니다.ba
if c in text:
def ab_with_check(text):
for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
if ch in text:
text = text.replace(ch,"\\"+ch)
def ba_without_check(text):
chars = "\\`*_{}[]()>#+-.!$"
for c in chars:
text = text.replace(c, "\\" + c)
Python 2.7.14 및 3.6.3 및 이전 세트와 다른 시스템에서 루프 당 μs 시간은 직접 비교할 수 없습니다.
╭────────────╥──────┬───────────────┬──────┬──────────────────╮
│ Py, input ║ ab │ ab_with_check │ ba │ ba_without_check │
╞════════════╬══════╪═══════════════╪══════╪══════════════════╡
│ Py2, short ║ 8.81 │ 4.22 │ 3.45 │ 8.01 │
│ Py3, short ║ 5.54 │ 1.34 │ 1.46 │ 5.34 │
├────────────╫──────┼───────────────┼──────┼──────────────────┤
│ Py2, long ║ 9.3 │ 7.15 │ 6.85 │ 8.55 │
│ Py3, long ║ 7.43 │ 4.38 │ 4.41 │ 7.02 │
└────────────╨──────┴───────────────┴──────┴──────────────────┘
우리는 결론을 내릴 수 있습니다.
수표가있는 사람은 수표가없는 사람보다 최대 4 배 빠릅니다.
ab_with_check
파이썬 3에서는 약간 우위에 있지만, ba
체크하면 파이썬 2에서는 우위에 있습니다.
그러나 여기서 가장 큰 교훈은 Python 3이 Python 2보다 최대 3 배 빠릅니다 . 가장 느린 Python 3과 Python 2에서 가장 큰 차이는 없습니다!
if c in text:
필요 ba
합니까?
1.45 usec per loop
: 그리고없이 5.3 usec per loop
함께 긴 문자열 : 4.38 usec per loop
및없이 : 7.03 usec per loop
. (이것은 다른 기계이기 때문에 위의 결과와 직접 비교할 수는 없습니다.)
replace
에만 호출 되기 때문이라고 생각합니다 . c
text
ba
ab
>>> string="abc&def#ghi"
>>> for ch in ['&','#']:
... if ch in string:
... string=string.replace(ch,"\\"+ch)
...
>>> print string
abc\&def\#ghi
string=string.replace(ch,"\\"+ch)
합니까? 단지가 string.replace(ch,"\\"+ch)
충분?
replace
이와 같은 기능을 간단히 연결
strs = "abc&def#ghi"
print strs.replace('&', '\&').replace('#', '\#')
# abc\&def\#ghi
교체품이 더 많아 질 경우, 일반적인 방법으로이 작업을 수행 할 수 있습니다
strs, replacements = "abc&def#ghi", {"&": "\&", "#": "\#"}
print "".join([replacements.get(c, c) for c in strs])
# abc\&def\#ghi
다음은 str.translate
and를 사용하는 python3 방법입니다 str.maketrans
.
s = "abc&def#ghi"
print(s.translate(str.maketrans({'&': '\&', '#': '\#'})))
인쇄 된 문자열은 abc\&def\#ghi
입니다.
.translate()
것이 세 개의 체인 .replace()
(CPython 3.6.4 사용) 보다 느립니다 .
replace()
나 자신 을 사용 하지만 완전성을 위해이 답변을 추가했습니다.
'\#'
유효합니까? 그것은 안 r'\#'
나 '\\#'
? 아마도 코드 블록 형식 문제 일 수 있습니다.
항상 백 슬래시를 추가 하시겠습니까? 그렇다면 시도하십시오
import re
rx = re.compile('([&#])')
# ^^ fill in the characters here.
strs = rx.sub('\\\\\\1', strs)
가장 효율적인 방법은 아니지만 가장 쉬운 방법이라고 생각합니다.
r'\\\1'
파티에 늦었지만 답변을 찾을 때 까지이 문제로 많은 시간을 잃었습니다.
짧고 달콤한, translate
우월합니다replace
. 시간 최적화에 따른 기능에 더 관심이있는 경우을 사용하지 마십시오 replace
.
또한 사용하는 translate
문자 집합을 대체하는 데 사용되는 문자 집합 중복 교체 할 경우 당신이 모르는 경우.
지목 사항:
를 사용 replace
하면 코드 조각이 순진하게 "1234".replace("1", "2").replace("2", "3").replace("3", "4")
반환 "2344"
되지만 실제로 반환됩니다 "4444"
.
번역은 원래 OP가 원하는 것을 수행하는 것으로 보입니다.
참고로, OP에는 거의 사용되지 않지만 다른 독자에게는 유용 할 수 있습니다 (공감하지 마십시오. 알고 있습니다).
다소 어리석지 만 흥미로운 연습으로, 파이썬 함수 프로그래밍을 사용하여 여러 문자를 바꿀 수 있는지 확인하고 싶었습니다. 나는 이것이 replace ()를 두 번 호출하는 것보다 이길 수 없다고 확신합니다. 그리고 성능이 문제라면 녹, C, 줄리아, 펄, 자바, 자바 스크립트 및 어색한 부분에서 쉽게 이길 수 있습니다. Cython을 통해 가속화 된 pytoolz 라는 외부 '도우미'패키지를 사용합니다 ( cytoolz, 그것은 pypi 패키지입니다 ).
from cytoolz.functoolz import compose
from cytoolz.itertoolz import chain,sliding_window
from itertools import starmap,imap,ifilter
from operator import itemgetter,contains
text='&hello#hi&yo&'
char_index_iter=compose(partial(imap, itemgetter(0)), partial(ifilter, compose(partial(contains, '#&'), itemgetter(1))), enumerate)
print '\\'.join(imap(text.__getitem__, starmap(slice, sliding_window(2, chain((0,), char_index_iter(text), (len(text),))))))
아무도 이것을 사용하여 여러 번 바꾸기를 귀찮게하지 않기 때문에 이것을 설명조차하지 않을 것입니다. 그럼에도 불구하고, 나는이 일을 어느 정도 성취했다고 느꼈고 다른 독자들에게 영감을 주거나 코드 난독 화 대회에서 이길 수 있다고 생각했습니다.
python2.7 및 python3. *에서 사용 가능한 reduce를 사용하면 깨끗하고 파이썬적인 방식으로 여러 하위 문자열을 쉽게 바꿀 수 있습니다.
# Lets define a helper method to make it easy to use
def replacer(text, replacements):
return reduce(
lambda text, ptuple: text.replace(ptuple[0], ptuple[1]),
replacements, text
)
if __name__ == '__main__':
uncleaned_str = "abc&def#ghi"
cleaned_str = replacer(uncleaned_str, [("&","\&"),("#","\#")])
print(cleaned_str) # "abc\&def\#ghi"
python2.7에서는 reduce를 가져올 필요가 없지만 python3. *에서는 functools 모듈에서 가져와야합니다.
문자를 대체하는 간단한 루프 일 수도 있습니다.
a = '&#'
to_replace = ['&', '#']
for char in to_replace:
a = a.replace(char, "\\"+char)
print(a)
>>> \&\#