대소 문자를 구분하지 않는 'in'-Python
나는 표현을 좋아한다
if 'MICHAEL89' in USERNAMES:
...
USERNAMES
목록이 어디 있어요
대소 문자를 구분하지 않는 항목을 일치시키는 방법이 있습니까? 아니면 사용자 지정 방법을 사용해야합니까? 이를 위해 추가 코드를 작성해야하는지 궁금합니다.
모두에게 감사 드려요!
if 'MICHAEL89' in (name.upper() for name in USERNAMES):
...
또는
if 'MICHAEL89' in map(str.upper, USERNAMES):
...
또는 사용자 정의 방법을 만들 수 있습니다.
난 당신이 비 침습적 수 있도록 래퍼를 만들 것 입니다. 최소한, 예를 들어 ... :
class CaseInsensitively(object):
def __init__(self, s):
self.__s = s.lower()
def __hash__(self):
return hash(self.__s)
def __eq__(self, other):
# ensure proper comparison between instances of this class
try:
other = other.__s
except (TypeError, AttributeError):
try:
other = other.lower()
except:
pass
return self.__s == other
이제 if CaseInsensitively('MICHAEL89') in whatever:
필요에 따라 동작해야합니다 (오른쪽이 목록, dict 또는 set인지 여부). (문자열 포함에 대해 비슷한 결과를 얻으려면 더 많은 노력이 필요할 수 있습니다 unicode
.
일반적으로 (적어도 적어도) 원하는 방식으로 동작하도록 객체를 형성합니다. name in USERNAMES
대소 문자를 구분하지 않으므로 USERNAMES
변경해야합니다.
class NameList(object):
def __init__(self, names):
self.names = names
def __contains__(self, name): # implements `in`
return name.lower() in (n.lower() for n in self.names)
def add(self, name):
self.names.append(name)
# now this works
usernames = NameList(USERNAMES)
print someone in usernames
이것에 대한 좋은 점은 클래스 외부의 코드를 변경하지 않고도 많은 개선을위한 길을 열었다는 것입니다. 예를 들어 self.names
빠른 조회를 위해 세트를 변경 하거나 (n.lower() for n in self.names)
한 번만 계산 하여 클래스에 저장할 수 있습니다.
추가 코드를 작성해야한다고 생각합니다. 예를 들면 다음과 같습니다.
if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
...
이 경우 모든 항목 USERNAMES
을 대문자 로 변환하여 새 목록을 만든 다음이 새 목록과 비교합니다.
최신 정보
으로 @viraptor는 말한다, 대신의 발전기를 사용하는 것이 더 나은 것입니다 map
. @Nathon 의 답변을 참조하십시오 .
한 가지 방법이 있습니다.
if string1.lower() in string2.lower():
...
이것이 작동 하려면 string1
및 string2
객체 유형이 모두 이어야합니다 string
.
str.casefold
is recommended for case-insensitive string matching. @nmichaels's solution can trivially be adapted.
Use either:
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
Or:
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
As per the docs:
Casefolding is similar to lowercasing but more aggressive because it is intended to remove all case distinctions in a string. For example, the German lowercase letter 'ß' is equivalent to "ss". Since it is already lowercase,
lower()
would do nothing to 'ß';casefold()
converts it to "ss".
You could do
matcher = re.compile('MICHAEL89', re.IGNORECASE)
filter(matcher.match, USERNAMES)
Update: played around a bit and am thinking you could get a better short-circuit type approach using
matcher = re.compile('MICHAEL89', re.IGNORECASE)
if any( ifilter( matcher.match, USERNAMES ) ):
#your code here
The ifilter
function is from itertools, one of my favorite modules within Python. It's faster than a generator but only creates the next item of the list when called upon.
My 5 (wrong) cents
'a' in "".join(['A']).lower()
UPDATE
Ouch, totally agree @jpp, I'll keep as an example of bad practice :(
참고URL : https://stackoverflow.com/questions/3627784/case-insensitive-in-python
'development' 카테고리의 다른 글
Android M 권한 : shouldShowRequestPermissionRationale () 함수 사용에 혼란 (0) | 2020.06.27 |
---|---|
Chrome을 사용하여 요소에 바인딩 된 이벤트를 찾는 방법 (0) | 2020.06.27 |
Chrome과 IE가 서버로 보내는 User-Agent에“Mozilla 5.0”을 넣는 이유는 무엇입니까? (0) | 2020.06.27 |
도메인 간 양식 게시 (0) | 2020.06.27 |
git에서 풀-풀 병합 커밋 메시지를 요구하는 이유는 무엇입니까? (0) | 2020.06.27 |