不区分大小写'in' – Python

我喜欢用这个expression

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:应该按照要求行事(不pipe右侧是列表,字典还是集合)。 (可能需要更多的努力来获得类似的结果,包括string,避免在某些涉及unicode警告等)。

通常(至less在oop中)你塑造你的对象来performance你想要的方式。 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的答案 。

你可以做

 matcher = re.compile('MICHAEL89', re.IGNORECASE) filter(matcher.match, USERNAMES) 

更新:玩了一下,我以为你可以使用更好的短路types的方法

 matcher = re.compile('MICHAEL89', re.IGNORECASE) if any( ifilter( matcher.match, USERNAMES ) ): #your code here 

ifilter函数来自itertools,它是Python中我最喜欢的模块之一。 它比生成器更快,但是只有在调用时才会创build列表的下一个项目。

这里有一个方法:

 if string1.lower() in string2.lower(): ...