不区分大小写的'in

219 投票
12 回答
197709 浏览
提问于 2025-04-16 03:38

我喜欢使用这个表达式

if 'MICHAEL89' in USERNAMES:
    ...

这里的 USERNAMES 是一个列表。


有没有办法让匹配不区分大小写,还是说我需要写一个自定义的方法?我只是想知道是否需要额外写代码来实现这个功能。

12 个回答

21

我会做一个包装器,这样你就可以不干扰其他代码。最简单的例子是...:

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的情况下出现警告等等。

53

str.casefold 是用来进行不区分大小写的字符串匹配的推荐方法。@nmichaels的解决方案 可以很简单地进行调整。

你可以使用以下任意一种方法:

if 'MICHAEL89'.casefold() in (name.casefold() for name in USERNAMES):

或者:

if 'MICHAEL89'.casefold() in map(str.casefold, USERNAMES):

根据文档的说明:

大小写折叠(casefolding)类似于将字母转换为小写,但它的处理更彻底,因为它的目的是去掉字符串中的所有大小写区别。例如,德语的小写字母 'ß' 等同于 "ss"。由于 'ß' 本身已经是小写,使用 lower() 方法对它没有任何作用;而 casefold() 方法则会把它转换成 "ss"。

256
username = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
    ...

另外:

if username.upper() in map(str.upper, USERNAMES):
    ...

或者,是的,你可以创建一个自定义的方法。

撰写回答