대소문자를 구분하지 않는 '입력'
나는 이 표현을 쓰는 것을 좋아한다.
if 'MICHAEL89' in USERNAMES:
...
어디에USERNAMES
는 리스트입니다.
대소문자를 구분하지 않는 아이템을 대조하는 방법이나 커스텀 방식을 사용해야 합니까?여기에 추가 코드를 쓸 필요가 있는지 궁금해서요.
username = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
...
대체 방법:
if username.upper() in map(str.upper, USERNAMES):
...
또는 사용자 지정 방법을 만들 수도 있습니다.
str.casefold
는 대소문자를 구분하지 않는 문자열 매칭에 권장됩니다.@nmichaels의 용액은 트라이얼하게 적응할 수 있다.
다음 중 하나를 사용합니다.
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
또는 다음 중 하나를 선택합니다.
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
문서에 따르면:
케이스 폴딩은 소문자와 비슷하지만 문자열 내의 대소문자를 모두 제거하는 것을 목적으로 하기 때문에 더 적극적입니다.예를 들어 독일어 소문자 '''는 'ss'에 해당합니다.이미 소문자이기 때문에
lower()
아무것도 하지 않는다.casefold()
ss로 변환합니다.
네가 비침습적일 수 있도록 포장지를 만들거야예를 들어 최소한...:
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:
는, 필요에 따라서 동작합니다(오른쪽이 리스트, 딕트, 또는 세트).(문자열 포함에 대해 유사한 결과를 얻기 위해서는 더 많은 노력이 필요할 수 있으며, 다음과 같은 경우에 경고를 피해야 합니다.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 string1.lower() in string2.lower():
...
이게 작동하려면 둘 다string1
그리고.string2
개체는 유형이어야 합니다.string
.
코드를 좀 더 작성하셔야 할 것 같아요.예를 들어 다음과 같습니다.
if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
...
이 경우 모든 엔트리가 다음 위치에 있는 새 목록을 만듭니다.USERNAMES
대문자로 변환한 후 이 새 목록과 비교합니다.
갱신하다
@viraptor의 말처럼 발전기를 사용하면map
@Nathon의 답변을 참조하십시오.
할 수 있다
matcher = re.compile('MICHAEL89', re.IGNORECASE)
filter(matcher.match, USERNAMES)
업데이트: 좀 더 나은 단락 유형 접근 방법을 얻을 수 있을 것으로 생각됩니다.
matcher = re.compile('MICHAEL89', re.IGNORECASE)
if any( ifilter( matcher.match, USERNAMES ) ):
#your code here
그ifilter
기능은 Python에서 내가 가장 좋아하는 모듈 중 하나인 itertools에서 가져온 것입니다.생성기보다 빠르지만 호출 시 목록의 다음 항목만 생성합니다.
한 줄에 정리하자면, 저는 이렇게 했습니다.
if any(([True if 'MICHAEL89' in username.upper() else False for username in USERNAMES])):
print('username exists in list')
하지만 시간적으로 테스트하진 않았어요.나는 그것이 얼마나 빠르고 효율적인지 잘 모르겠다.
5센트 (잘못)
""의 "a"는 "join(["A")".lower()의 "a"입니다.
갱신하다
아, @jpp, 완전히 동의해, 나쁜 관행의 예를 들겠습니다.
사전에는 목록 대신 이것이 필요했는데, 요헨 솔루션이 그 경우에 가장 우아했기 때문에 조금 수정했습니다.
class CaseInsensitiveDict(dict):
''' requests special dicts are case insensitive when using the in operator,
this implements a similar behaviour'''
def __contains__(self, name): # implements `in`
return name.casefold() in (n.casefold() for n in self.keys())
할 수 .USERNAMESDICT = CaseInsensitiveDict(USERNAMESDICT)
를 사용합니다.if 'MICHAEL89' in USERNAMESDICT:
이 튜토리얼의 예:
list1 = ["Apple", "Lenovo", "HP", "Samsung", "ASUS"]
s = "lenovo"
s_lower = s.lower()
res = s_lower in (string.lower() for string in list1)
print(res)
언급URL : https://stackoverflow.com/questions/3627784/case-insensitive-in
'programing' 카테고리의 다른 글
Numpy에서 벡터의 크기를 어떻게 구하나요? (0) | 2022.09.24 |
---|---|
[첫 글자가 B로 시작]에서 모두 선택합니다. (0) | 2022.09.24 |
자바스크립트로 div 콘텐츠를 변경하려면 어떻게 해야 하나요? (0) | 2022.09.24 |
MariaDB: 'AS'를 사용하지 않고 중복된 열 이름을 검색할 수 있습니까? (0) | 2022.09.24 |
데이터에서의 월과 연도의 갭 메우기 (0) | 2022.09.24 |