不区分大小写“in”

发布于 2024-09-17 10:02:13 字数 181 浏览 8 评论 0原文

表达式

if 'MICHAEL89' in USERNAMES:
    ...

我喜欢使用USERNAMES 是列表的


。有什么方法可以匹配不区分大小写的项目,还是我需要使用自定义方法?只是想知道是否需要为此编写额外的代码。

I love using the expression

if 'MICHAEL89' in USERNAMES:
    ...

where USERNAMES is a list.


Is there any way to match items with case insensitivity or do I need to use a custom method? Just wondering if there is a need to write extra code for this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

桃扇骨 2024-09-24 10:02:13
username = 'MICHAEL89'
if username.upper() in (name.upper() for name in USERNAMES):
    ...

或者:

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

或者,是的,您可以创建自定义方法。

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

Alternatively:

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

Or, yes, you can make a custom method.

酒中人 2024-09-24 10:02:13

建议使用 str.casefold 进行不区分大小写的字符串匹配。 @nmichaels 的解决方案可以轻松进行调整。

使用:

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

或者:

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

根据 docs

大小写与小写类似,但更具侵略性,因为它
旨在删除字符串中的所有大小写区别。例如,
德语小写字母“ß”相当于“ss”。既然是
已经是小写了,lower() 对 'ß' 没有任何作用; casefold()
将其转换为“ss”。

str.casefold is recommended for case-insensitive string matching. @nmichaels's solution can trivially be adapted.

Use either:

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

Or:

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

As per the docs:

Casefolding is similar to lowercasing but more aggressive because it
is intended to remove all case distinctions in a string. For example,
the German lowercase letter 'ß' is equivalent to "ss". Since it is
already lowercase, lower() would do nothing to 'ß'; casefold()
converts it to "ss".

本王不退位尔等都是臣 2024-09-24 10:02:13

我会做一个包装,这样你就可以是非侵入性的。至少,例如...:

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 another: 应该按要求运行(无论右侧是列表、字典还是集合)。 (可能需要付出更多努力才能实现字符串包含的类似结果,避免在某些涉及 unicode 的情况下出现警告等)。

I would make a wrapper so you can be non-invasive. Minimally, for example...:

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

Now, if CaseInsensitively('MICHAEL89') in whatever: should behave as required (whether the right-hand side is a list, dict, or set). (It may require more effort to achieve similar results for string inclusion, avoid warnings in some cases involving unicode, etc).

半夏半凉 2024-09-24 10:02:13

通常(至少在 oop 中)你可以塑造你的对象,让它按照你想要的方式运行。 USERNAMES 中的 name 不区分大小写,因此 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)将其存储在课堂上等等......

Usually (in oop at least) you shape your object to behave the way you want. name in USERNAMES is not case insensitive, so USERNAMES needs to change:

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

The great thing about this is that it opens the path for many improvements, without having to change any code outside the class. For example, you could change the self.names to a set for faster lookups, or compute the (n.lower() for n in self.names) only once and store it on the class and so on ...

强者自强 2024-09-24 10:02:13

一种方法是:

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

要使其工作,string1string2 对象都必须是 string 类型。

Here's one way:

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

For this to work, both string1 and string2 objects must be of type string.

戏舞 2024-09-24 10:02:13

我认为你必须编写一些额外的代码。例如:

if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
   ...

在本例中,我们正在形成一个新列表,其中 USERNAMES 中的所有条目都转换为大写,然后与这个新列表进行比较。

更新

正如@viraptor所说,使用生成器而不是更好地图。请参阅 @Nathon答案

I think you have to write some extra code. For example:

if 'MICHAEL89' in map(lambda name: name.upper(), USERNAMES):
   ...

In this case we are forming a new list with all entries in USERNAMES converted to upper case and then comparing against this new list.

Update

As @viraptor says, it is even better to use a generator instead of map. See @Nathon's answer.

素罗衫 2024-09-24 10:02:13

你可以做

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

更新:玩了一下,我想你可以使用来自 itertools 的 ifilter 函数获得更好的短路类型方法

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

,itertools 是我最喜欢的 Python 模块之一。它比生成器更快,但仅在调用时创建列表的下一项。

You could do

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

Update: played around a bit and am thinking you could get a better short-circuit type approach using

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

The ifilter function is from itertools, one of my favorite modules within Python. It's faster than a generator but only creates the next item of the list when called upon.

氛圍 2024-09-24 10:02:13

为了将它放在一行中,这就是我所做的:

if any(([True if 'MICHAEL89' in username.upper() else False for username in USERNAMES])):
    print('username exists in list')

不过我没有在时间上测试它。我不确定它有多快/高效。

To have it in one line, this is what I did:

if any(([True if 'MICHAEL89' in username.upper() else False for username in USERNAMES])):
    print('username exists in list')

I didn't test it time-wise though. I am not sure how fast/efficient it is.

任性一次 2024-09-24 10:02:13

本教程中的示例:

list1 = ["Apple", "Lenovo", "HP", "Samsung", "ASUS"]

s = "lenovo"
s_lower = s.lower()

res = s_lower in (string.lower() for string in list1)

print(res)

Example from this tutorial:

list1 = ["Apple", "Lenovo", "HP", "Samsung", "ASUS"]

s = "lenovo"
s_lower = s.lower()

res = s_lower in (string.lower() for string in list1)

print(res)
昨迟人 2024-09-24 10:02:13

我的 5 美分(错误)

'a' in "".join(['A']).lower()

更新

哎哟,完全同意@jpp,我将保留作为不良实践的例子:(

My 5 (wrong) cents

'a' in "".join(['A']).lower()

UPDATE

Ouch, totally agree @jpp, I'll keep as an example of bad practice :(

荭秂 2024-09-24 10:02:13

我需要这个字典而不是列表,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) 并使用 <代码>如果 USERNAMESDICT 中为“MICHAEL89”:

I needed this for a dictionary instead of list, Jochen solution was the most elegant for that case so I modded it a bit:

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())

now you can convert a dictionary like so USERNAMESDICT = CaseInsensitiveDict(USERNAMESDICT) and use if 'MICHAEL89' in USERNAMESDICT:

温柔少女心 2024-09-24 10:02:13

我正在使用 Pyhton 3.10.5

假设我有一个列表

USERNAMES = ['joy23', 'michael89', 'rony224', 'samrat445']

现在如果我想检查 'michael89' 是否在列表中而不考虑大小写,以下代码有效:

'michael89'.casefold() in USERNAMES

输出将为 true。

再次,如果我想检查“MICHAEL89”是否在列表中而不考虑大小写,代码是:

'MICHAEL89'.casefold() in USERNAMES

输出也将为 true。

'miCHAel89'.casefold() in USERNAMES

这再次返回 true。
示例前面的解释

所以这里的主要问题是 USERNAMES 列表应该只包含小写字母。如果将USERNAMES的所有项目都以小写字母保存。您可以简单地使用解决问题:

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

I am using Pyhton 3.10.5

Suppose I have a list

USERNAMES = ['joy23', 'michael89', 'rony224', 'samrat445']

Now if I want to check if 'michael89' is on the list without considering the case, The following code works:

'michael89'.casefold() in USERNAMES

The output will be true.

Again if I want to check if 'MICHAEL89' is on the list without considering the case, The code is:

'MICHAEL89'.casefold() in USERNAMES

The output will also be true.

'miCHAel89'.casefold() in USERNAMES

This returns true again.
Example of the previous explanation

So the main catch here is the USERNAMES list should only contain lowercase letters. If you save all the items of USERNAMES in lowercase letters. You can simply solve the problem using:

if 'MICHAEL89'.casefold() in USERNAMES:
    ......
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文