我喜欢使用表达式
if 'MICHAEL89' in USERNAMES:
...
其中USERNAMES
是一个列表
有没有办法匹配不区分大小写的项目,还是需要使用自定义方法?只是想知道是否需要为此编写额外的代码。
感谢大家!
答案 0 :(得分:149)
if 'MICHAEL89' in (name.upper() for name in USERNAMES):
...
可替换地:
if 'MICHAEL89' in map(str.upper, USERNAMES):
...
或者,是的,您可以制作自定义方法。
答案 1 :(得分:17)
我会创建一个包装,这样你就可以是非侵入性的。最低限度,例如......:
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
的情况下避免警告等。)
答案 2 :(得分: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
关于这一点的好处在于它为许多改进打开了路径,而无需更改类外的任何代码。例如,您可以将self.names
更改为更快查找的集合,或仅计算(n.lower() for n in self.names)
一次并将其存储在类中等等...
答案 3 :(得分:6)
我认为你必须写一些额外的代码。例如:
if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
...
在这种情况下,我们正在形成一个新列表,其中USERNAMES
中的所有条目都转换为大写,然后与此新列表进行比较。
更新
答案 4 :(得分:5)
以这种方式:
if string1.lower() in string2.lower():
...
为此,string1
和string2
个对象的类型必须为string
。
答案 5 :(得分:4)
你可以做到
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中最喜欢的模块之一。它比生成器更快,但只在调用时才创建列表的下一个项目。
答案 6 :(得分:4)
str.casefold
进行不区分大小写的字符串匹配。 @nmichaels's solution可以轻松改编。
使用以下任一方法:
if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):
或者:
if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):
按照docs:
折页与下折类似,但更具攻击性,因为它 旨在删除字符串中的所有大小写区别。例如, 德国小写字母“ß”等效于“ ss”。因为它是
lower()
已经小写了,对“ß”不起作用;casefold()
将其转换为“ ss”。
答案 7 :(得分:0)
我的5分(错误)
'a'in“” .join(['A'])。lower()
哦,完全同意@jpp,我将举一个不良做法的例子:(
答案 8 :(得分:0)
我需要一个字典而不是列表,Jochen解决方案在这种情况下是最优雅的,所以我对其进行了修改:
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:
答案 9 :(得分:0)
要一行完成,这就是我所做的:
git rebase -X ours
虽然我没有及时进行测试。我不确定它的速度/效率。