Rad*_*Hex 136 python string list case-insensitive
我喜欢用这个表达方式
if 'MICHAEL89' in USERNAMES:
...
Run Code Online (Sandbox Code Playgroud)
USERNAMES
列表在哪里
有没有办法匹配不区分大小写的项目或我需要使用自定义方法?只是想知道是否需要为此编写额外的代码.
谢谢大家!
nmi*_*els 161
if 'MICHAEL89' in (name.upper() for name in USERNAMES):
...
Run Code Online (Sandbox Code Playgroud)
或者:
if 'MICHAEL89' in map(str.upper, USERNAMES):
...
Run Code Online (Sandbox Code Playgroud)
或者,是的,您可以制作自定义方法.
Ale*_*lli 19
我会做一个包装,所以你可以是非侵入性的.最低限度,例如...:
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
Run Code Online (Sandbox Code Playgroud)
现在,if CaseInsensitively('MICHAEL89') in whatever:
应该按照要求行事(无论右侧是列表,字典还是集合).(可能需要更多的努力来实现字符串包含的类似结果,在某些情况下避免警告unicode
等).
Joc*_*zel 10
通常(至少在oop中)你塑造你的对象以按照你想要的方式行事.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
Run Code Online (Sandbox Code Playgroud)
关于这一点的好处在于它为许多改进打开了路径,而无需更改类外的任何代码.例如,您可以将更self.names
改为更快的查找集,或者(n.lower() for n in self.names)
只计算一次并将其存储在类中,依此类推......
我想你必须写一些额外的代码.例如:
if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
...
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们正在形成一个新列表,其中所有条目都USERNAMES
转换为大写,然后与此新列表进行比较.
更新
正如@viraptor所说,使用发电机代替它更好map
.看@Nathon的回答.
这是一种方法:
if string1.lower() in string2.lower():
...
Run Code Online (Sandbox Code Playgroud)
为此,string1
和string2
对象都必须是type string
。
str.casefold
建议使用不区分大小写的字符串匹配。@nmichaels的解决方案可以轻松调整。
使用以下任一方法:
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
Run Code Online (Sandbox Code Playgroud)
要么:
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
Run Code Online (Sandbox Code Playgroud)
根据文档:
大小写折叠类似于小写字母,但更具侵略性,因为它旨在消除字符串中的所有大小写区别。例如,德语小写字母“ß”等效于“ ss”。由于它已经是小写字母,
lower()
因此对“ß”无效。casefold()
将其转换为“ ss”。
你可以做
matcher = re.compile('MICHAEL89', re.IGNORECASE)
filter(matcher.match, USERNAMES)
Run Code Online (Sandbox Code Playgroud)
更新:玩了一下,我想你可以使用更好的短路类型方法
matcher = re.compile('MICHAEL89', re.IGNORECASE)
if any( ifilter( matcher.match, USERNAMES ) ):
#your code here
Run Code Online (Sandbox Code Playgroud)
该ifilter
函数来自 itertools,这是我最喜欢的 Python 模块之一。它比生成器快,但仅在调用时创建列表的下一项。