我喜欢用这个表达方式
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:
应该按照要求行事(无论右侧是列表,字典还是集合)。 (可能需要更多的努力来实现字符串包含的类似结果,在某些涉及unicode
的情况下避免警告等)。
通常(至少在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
关于这一点的好处在于它为许多改进打开了路径,而无需更改类外的任何代码。例如,你可以将self.names
更改为一组以便更快地查找,或者只计算一次(n.lower() for n in self.names)
并将其存储在类中,依此类推......
这是一种方式:
if string1.lower() in string2.lower():
...
为此,string1
和string2
对象必须是string
类型。
你可以做到
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
函数来自itertools,这是我在Python中最喜欢的模块之一。它比生成器更快,但只在调用时才创建列表的下一个项目。
str.casefold
建议用于不区分大小写的字符串匹配。 @nmichaels's solution可以简单地适应。
使用:
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
要么:
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
根据docs:
Casefolding类似于lowercasing但更具攻击性,因为它旨在删除字符串中的所有大小写区别。例如,德语小写字母'ß'相当于“ss”。由于它已经是小写的,
lower()
对'ß'没有任何作用;casefold()
将其转换为“ss”。
我的5(错)美分
“a”in“”。join(['A'])。lower()
哎哟,完全同意@jpp,我会继续作为不良做法的一个例子:(