不区分大小写'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(): ...