파이썬을 사용하여 문자열에서 특정 문자를 제거하려고합니다. 이것은 지금 사용중인 코드입니다. 불행히도 문자열에는 아무런 영향을 미치지 않는 것으로 보입니다.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
이 작업을 올바르게 수행하려면 어떻게합니까?
파이썬을 사용하여 문자열에서 특정 문자를 제거하려고합니다. 이것은 지금 사용중인 코드입니다. 불행히도 문자열에는 아무런 영향을 미치지 않는 것으로 보입니다.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
이 작업을 올바르게 수행하려면 어떻게합니까?
답변:
파이썬의 문자열은 변경할 수 없습니다 ( 변경 불가 ). 이로 인해 line.replace(...)
기존 문자열을 변경하지 않고 새 문자열을 만드는 것이 효과입니다 . 당신은 할 필요가 리 바인드 로 (할당)을 line
그 변수를 제거하는 문자로, 새로운 값을 갖기 위해.
또한, 당신이하고있는 방식은 상대적으로 느리게 진행됩니다. 또한 경험이 많은 pythonator에게는 약간 혼동 될 수 있습니다. 경험이 많은 pythonator는 이중 중첩 구조를보고 더 복잡한 무언가가 진행되고 있다고 생각합니다.
Python 2.6 및 최신 Python 2.x 버전 *부터는 대신을 사용할 수 있습니다 str.translate
(하지만 Python 3 차이점에 대해서는 계속 읽으십시오).
line = line.translate(None, '!@#$')
또는 정규식 대체 re.sub
import re
line = re.sub('[!@#$]', '', line)
대괄호로 묶인 문자는 문자 클래스를 구성합니다 . line
해당 클래스 에 있는 모든 문자 는 두 번째 매개 변수로 대체됩니다 sub
. 빈 문자열.
Python 3에서 문자열은 유니 코드입니다. 약간 다르게 번역해야합니다. kevpie는 답변 중 하나 에 대한 의견 에서 이것을 언급했으며에 대한 설명서에 나와str.translate
있습니다.
translate
유니 코드 문자열 의 메소드를 호출 할 때 위에서 사용한 두 번째 매개 변수를 전달할 수 없습니다. None
첫 번째 매개 변수로 전달할 수도 없습니다 . 대신 번역 테이블 (일반적으로 사전)을 유일한 매개 변수로 전달합니다. 이 표 는 문자 의 서수 값 (즉, 호출 한 결과 ord
)을 해당 문자 의 서수 값 에 매핑합니다.이 서수 는 문자를 None
삭제해야 함을 나타냅니다.
유니 코드 문자열로 위의 춤을 수행하려면 다음과 같이 호출하십시오.
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
여기 dict.fromkeys
하고 map
간결 포함하는 사전을 생성하는 데 사용되는
{ord('!'): None, ord('@'): None, ...}
더 간단한 방법으로 다른 답변에 따르면 번역 테이블을 작성하십시오.
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
또는 다음을 사용하여 동일한 번역 테이블을 만듭니다 str.maketrans
.
unicode_line = unicode_line.translate(str.maketrans('', '', '!@#$'))
* 이전 파이썬과의 호환성을 위해 다음 대신에 "널"변환 테이블을 작성할 수 있습니다 None
.
import string
line = line.translate(string.maketrans('', ''), '!@#$')
여기 string.maketrans
만드는 데 사용되는 변환 테이블을 0 ~ 255 서수 값으로 문자를 포함하는 단지 문자열이다.
line.translate
단 하나 개의 인수와 최초의 솔루션 작동하지 않습니다 소요
line.translate({ord(i):None for i in '!@#$'})
"'"
은 문자 집합을 작성합니다.
notes = notes.translate({ord(i):None for i in '\"\''})
unicode_line.translate(str.maketrans('', '', '!@#$'))
. 또는unicode_line.translate(dict.fromkeys(map(ord, '!@#$')))
여기서 요점이 누락되었거나 다음과 같습니다.
string = "ab1cd1ef"
string = string.replace("1","")
print string
# result: "abcdef"
루프에 넣으십시오.
a = "a!b@c#d$"
b = "!@#$"
for char in b:
a = a.replace(char,"")
print a
# result: "abcd"
for char in b: a=a.replace(char,"")
string=string.replace("1","")
대신 해야 합니다. 예를 들어 루프 부분에서 이것을 말했지만 대부분의 사람들은 간단한 질문을 위해 코드로 먼저 손을 after 때까지 대답을 자세히 읽지 않습니다.
re.sub
파이썬 3.5부터 정규 표현식으로 쉽게 peasyre.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
>>> import re
>>> line = 'Q: Do I write ;/.??? No!!!'
>>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'
에서 정규 표현식 (정규식), |
논리적 인 OR과 \
실제 정규식 명령 수 있습니다 공백 및 특수 문자를 이스케이프합니다. 반면 에이 경우 빈 문자열 sub
로 대체를 나타냅니다 ''
.
문자열에서 특정 문자 만 허용 해야하는 역 요구 사항의 경우 set 보완 연산자로 정규식을 사용할 수 있습니다 [^ABCabc]
. 예를 들어 ASCII 문자, 숫자 및 하이픈을 제외한 모든 항목을 제거하려면 다음을 수행하십시오.
>>> import string
>>> import re
>>>
>>> phrase = ' There were "nine" (9) chick-peas in my pocket!!! '
>>> allow = string.letters + string.digits + '-'
>>> re.sub('[^%s]' % allow, '', phrase)
'Therewerenine9chick-peasinmypocket'
에서 파이썬 정규 표현식 문서 :
범위를 벗어나는 문자는 세트를 보완하여 일치시킬 수 있습니다. 세트의 첫 번째 문자가 인 경우 세트
'^'
에없는 모든 문자가 일치합니다. 예를 들어,[^5]
'5'를 제외한 모든 문자와[^^]
일치하고를 제외한 모든 문자와 일치합니다'^'
.^
세트의 첫 번째 문자가 아닌 경우 특별한 의미가 없습니다.
asker는 거의 그것을했다. 파이썬의 대부분의 것들과 마찬가지로 대답은 생각보다 간단합니다.
>>> line = "H E?.LL!/;O:: "
>>> for char in ' ?.!/;:':
... line = line.replace(char,'')
...
>>> print line
HELLO
중첩 된 if / for 루프를 수행 할 필요는 없지만 각 문자를 개별적으로 확인해야합니다.
line = line.translate(None, " ?.!/;:")
파이썬에서는 문자열을 변경할 수 없습니다. 이 replace
메서드는 교체 후 새 문자열을 반환합니다. 시험:
for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
line
됩니다.
내장 필터 기능을 사용하는 사람이 아직 아무도 없다는 것에 놀랐습니다 .
import operator
import string # only for the example you could use a custom string
s = "1212edjaq"
숫자가 아닌 모든 것을 걸러 내고 싶다고 가정 해보십시오. 필터 내장 메소드 사용 "...은 생성자 표현식과 동일합니다 (함수 (항목) 인 경우 반복 가능한 항목의 항목)" "[ Python 3 Builtins : Filter ]
sList = list(s)
intsList = list(string.digits)
obj = filter(lambda x: operator.contains(intsList, x), sList)))
파이썬 3에서 이것은 반환
>> <filter object @ hex>
인쇄 된 문자열을 얻으려면
nums = "".join(list(obj))
print(nums)
>> "1212"
효율성 측면에서 필터 순위가 어떻게되는지 잘 모르겠지만 목록 이해 등을 수행 할 때 사용하는 방법을 아는 것이 좋습니다.
최신 정보
논리적으로 필터가 작동하기 때문에 목록 이해도 사용할 수 있으며 내가 읽은 것에서 람다는 프로그래밍 기능 세계의 월스트리트 헤지 펀드 관리자이기 때문에 더 효율적이라고 생각됩니다. 또 다른 장점은 수입품이 필요없는 원 라이너라는 것입니다. 예를 들어 위에서 정의한 동일한 문자열 's'를 사용하면
num = "".join([i for i in s if i.isdigit()])
그게 다야. 반환 값은 원래 문자열의 숫자 인 모든 문자의 문자열입니다.
허용 / 허용 할 수없는 특정 문자 목록이있는 경우 목록 이해의 'if'부분 만 조정하면됩니다.
target_chars = "".join([i for i in s if i in some_list])
또는 대안으로
target_chars = "".join([i for i in s if i not in some_list])
operator.contains
사용하는 경우 사용할 이유가 없습니다 lambda
. lambda x: operator.contains(intsList, x)
철자가되어야합니다 lambda x: x in intsList
. 그렇지 않으면 C- 레벨 검사를 받으려고하면 intsList.__contains__
전혀 사용하지 않습니다 lambda
.
를 사용하면 filter
한 줄만 있으면됩니다.
line = filter(lambda char: char not in " ?.!/;:", line)
이것은 문자열을 반복 가능한 것으로 취급하고 lambda
반환되는 경우 모든 문자를 확인 합니다 True
.
>>> help(filter) Help on built-in function filter in module __builtin__: filter(...) filter(function or None, sequence) -> list, tuple, or string Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list.
이 작업을 수행 할 수있는 몇 가지 방법이 있습니다.
def attempt1(string):
return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])
def attempt2(string):
for v in ("a", "e", "i", "o", "u"):
string = string.replace(v, "")
return string
def attempt3(string):
import re
for v in ("a", "e", "i", "o", "u"):
string = re.sub(v, "", string)
return string
def attempt4(string):
return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")
for attempt in [attempt1, attempt2, attempt3, attempt4]:
print(attempt("murcielago"))
추신 : 대신 "?.! / ;:"를 사용하여 예제는 모음을 사용합니다 ... 그리고 "murcielago"는 박쥐를 말할 스페인어 단어입니다 ... 모든 모음을 포함하는 재미있는 단어 :)
PS2 : 성능에 관심이 있다면 다음과 같은 간단한 코드로 이러한 시도를 측정 할 수 있습니다.
import timeit
K = 1000000
for i in range(1,5):
t = timeit.Timer(
f"attempt{i}('murcielago')",
setup=f"from __main__ import attempt{i}"
).repeat(1, K)
print(f"attempt{i}",min(t))
내 상자에 당신은 얻을 것이다 :
attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465
따라서 try4 가이 특정 입력에 가장 빠른 것 같습니다.
list
을 attempt1
작성 "aeiou"
중이며 단순성 을 위해 튜플을 다시 작성할 수 있습니다 ( 목록을 작성하지 않고 제거 [
하고 ]
생성기로 전환 함). 에서 수많은 중간 중간 문자열을 생성 하고 한 번에 사용할 수있는 attemt2
여러 정규식 응용 프로그램을 attempt3
사용 r'[aeiou]'
합니다. 각각에는 결함이 있습니다. 여러 가지 방법으로 작업하는 것이 좋지만, 좋은 시도가되도록 수정하십시오
다음은 Python 2/3 호환 버전입니다. 번역 API가 변경되었으므로
def remove(str_, chars):
"""Removes each char in `chars` from `str_`.
Args:
str_: String to remove characters from
chars: String of to-be removed characters
Returns:
A copy of str_ with `chars` removed
Example:
remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
"""
try:
# Python2.x
return str_.translate(None, chars)
except TypeError:
# Python 3.x
table = {ord(char): None for char in chars}
return str_.translate(table)
dict.fromkeys(map(ord, '!@#$'))
지도를 만드는 데 사용 합니다.
map
일반적으로 list / dict / set / generator 이해력보다 읽기 어렵습니다. 귀도는 언어에서 그것을 제거 하고 싶었습니다 . 사용 fromkeys
하는 것도 약간 영리하며 문서 검사가 필요합니다.
str.maketrans('', '', chars)
경우 ord
변환과 dict
생성을 한 번에 처리하는 여야합니다 (와 쌍으로 설계되었으므로 의도가 더 분명하다는 것은 말할 것도 없습니다 str.translate
).
#!/usr/bin/python
import re
strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character
print nestr
'
문자열로 간주하기 위해 백 슬래시가 있습니다. docs.python.org/2/library/re.html
이건 어때요:
def text_cleanup(text):
new = ""
for i in text:
if i not in " ?.!/;:":
new += i
return new
리스트를 사용하여 다른 종류의 정규 표현식 또는 다른 패턴을 대체하기 위해 함수를 사용할 수도 있습니다. 이를 통해 정규 표현식, 문자 클래스 및 기본 텍스트 패턴을 혼합 할 수 있습니다. HTML과 같은 많은 요소를 대체해야 할 때 정말 유용합니다.
* NB : Python 3.x에서 작동
import re # Regular expression library
def string_cleanup(x, notwanted):
for item in notwanted:
x = re.sub(item, '', x)
return x
line = "<title>My example: <strong>A text %very% $clean!!</strong></title>"
print("Uncleaned: ", line)
# Get rid of html elements
html_elements = ["<title>", "</title>", "<strong>", "</strong>"]
line = string_cleanup(line, html_elements)
print("1st clean: ", line)
# Get rid of special characters
special_chars = ["[!@#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)
string_cleanup 함수에서는 문자열 x와 목록을 인수로 사용하지 않습니다. 해당 요소 또는 패턴 목록의 각 항목에 대해 대체가 필요한 경우 수행됩니다.
출력 :
Uncleaned: <title>My example: <strong>A text %very% $clean!!</strong></title>
1st clean: My example: A text %very% $clean!!
2nd clean: My example: A text very clean
내가 사용하는 방법은 아마도 효율적으로 작동하지 않지만 매우 간단합니다. 슬라이싱 및 서식을 사용하여 한 번에 여러 위치에서 여러 문자를 제거 할 수 있습니다. 예를 들면 다음과 같습니다.
words = "things"
removed = "%s%s" % (words[:3], words[-1:])
이로 인해 'this'라는 단어가 '제거'됩니다.
서식 은 인쇄 문자열 중간에 변수를 인쇄하는 데 매우 유용합니다. 변수 데이터 형식 뒤에 %를 사용하여 모든 데이터 형식을 삽입 할 수 있습니다 . 모든 데이터 유형은 % s 를 사용할 수 있고 부동 소수점 (일명 소수) 및 정수는 % d를 사용할 수 있습니다 .
슬라이싱 은 문자열을 복잡하게 제어하는 데 사용할 수 있습니다. words [: 3]을 넣을 때 문자열의 모든 문자를 처음부터 (콜론은 숫자 앞에, 이것은 처음부터 끝까지 의미합니다) 4 번째 문자 (4 번째 문자 포함)를 선택할 수 있습니다 캐릭터). 3이 4 번째 위치까지 같은 이유는 파이썬이 0에서 시작하기 때문입니다. 그런 다음 word [-1 :]을 넣을 때 마지막 두 번째 문자 (콜론은 숫자 뒤에 있음)를 의미합니다. -1을 넣으면 파이썬이 첫 번째 문자가 아닌 마지막 문자에서 카운트됩니다. 다시 말하지만, 파이썬은 0에서 시작합니다. 따라서 단어 [-1 :]은 기본적으로 '두 번째 마지막 문자부터 문자열의 끝까지'를 의미합니다.
따라서 제거하려는 문자 앞의 문자와 문자를 결합한 후 함께 샌드위치하여 원하지 않는 문자를 제거 할 수 있습니다. 그것을 소시지처럼 생각하십시오. 가운데는 더러워서 제거하고 싶습니다. 나는 단순히 원하는 두 끝을 잘라 내고 중간에 원하지 않는 부분없이 함께 두었습니다.
연속 된 여러 문자를 제거하려면 [] (슬라이스 부분)에서 숫자를 이동하면됩니다. 또는 다른 위치에서 여러 문자를 제거하려면 한 번에 여러 조각을 간단히 샌드위치로 묶을 수 있습니다.
예 :
words = "control"
removed = "%s%s" % (words[:2], words[-2:])
제거는 '쿨'과 같습니다.
words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])
제거는 'macs'와 같습니다.
이 경우 [3 : 5] 는 위치 3의 문자부터 위치 5의 문자를 의미합니다 (최종 위치의 문자 제외).
파이썬은 0부터 시작 하기 때문에 기억 해야합니다.
re 모듈의 정규 표현식 대체를 사용할 수 있습니다. ^ 표현식을 사용하면 문자열에서 원하는 것을 정확하게 선택할 수 있습니다.
import re
text = "This is absurd!"
text = re.sub("[^a-zA-Z]","",text) # Keeps only Alphabets
print(text)
이것에 대한 출력은 "Thisisabsurd"입니다. ^ 기호 뒤에 지정된 것만 나타납니다.
문자열 메서드 replace
는 원래 문자열을 수정하지 않습니다. 원본은 그대로두고 수정 된 사본을 반환합니다.
원하는 것은 다음과 같습니다. line = line.replace(char,'')
def replace_all(line, )for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
return line
그러나 문자를 제거 할 때마다 새 문자열을 작성하는 것은 매우 비효율적입니다. 대신 다음을 권장합니다.
def replace_all(line, baddies, *):
"""
The following is documentation on how to use the class,
without reference to the implementation details:
For implementation notes, please see comments begining with `#`
in the source file.
[*crickets chirp*]
"""
is_bad = lambda ch, baddies=baddies: return ch in baddies
filter_baddies = lambda ch, *, is_bad=is_bad: "" if is_bad(ch) else ch
mahp = replace_all.map(filter_baddies, line)
return replace_all.join('', join(mahp))
# -------------------------------------------------
# WHY `baddies=baddies`?!?
# `is_bad=is_bad`
# -------------------------------------------------
# Default arguments to a lambda function are evaluated
# at the same time as when a lambda function is
# **defined**.
#
# global variables of a lambda function
# are evaluated when the lambda function is
# **called**
#
# The following prints "as yellow as snow"
#
# fleece_color = "white"
# little_lamb = lambda end: return "as " + fleece_color + end
#
# # sometime later...
#
# fleece_color = "yellow"
# print(little_lamb(" as snow"))
# --------------------------------------------------
replace_all.map = map
replace_all.join = str.join
당신은 세트를 사용할 수 있습니다
charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])
filter
함수와 Lambda Expression :을 사용하는 것은 어떻 습니까filter(lambda ch: ch not in " ?.!/;:", line)
. 꽤 간결하고 효율적이라고 생각합니다. 물론 이름을 할당해야 할 새 문자열을 반환합니다.