如何在 Python 中将 any() 语句变为负数?

How to turn an any() statment negative in Python?

我正在为输入的电子邮件创建检查以查看它们是否只使用特定的字符。我想使用一个 any() 声明,基本上意味着 "if any item from the e-mail isn't in goodCharsEmail, do ..." 我想到了这个:

newEmail = ["m", "a", "i", "l", "@", "d", "o", "m", "a", "i", "n", ".", "c", "o", "m"] 

goodCharsEmail = ["a", "b", "c", "etc..."]

check =  any(item in newEmail for item in goodCharsEmail)
if check == True:
    print("bad request")
    quit

但我显然需要将 any() 语句设为负数,因为目前它与想要的结果完全相反。我该如何解决这个问题?

既然您提到您是 python 的新手,我会尽量做到非常详尽。如有重复请见谅。

首先,让我们看看 any() 做了什么。最简单的方式大概就是自己写一个简单的实现:

def any(sequence):
    for value in sequence:
        if value:
            return True
    return False

英文:它returns True当且仅当任何序列中的值是"true-ish"(例如a非零整数、非空列表、非空字符串等)。

既然在评论中提到了all(),那我们也一样吧:

def all(sequence):
    for value in sequence:
        if not value:
            return False
    return True

英语:它 returns True 当且仅当 所有 序列中的值都是真实的。与 any() 非常相似,不是吗?

其次,让我注意一点关于 python 字符串的事情:它们通常可以被认为是字符列表,并且可以这样处理。换句话说,不需要将字符分隔成单独的单字符字符串列表。

第三,我认为您的问题不在于 any() 函数,而在于您的列表理解(括号内的表达式)。你看,item in newEmail for item in goodCharsEmail 意味着你正在检查 goodCharsEmail 中的每个字符是否都出现在 newEmail 中。您真正想要的是相反的方式:newEmail 中的每个角色都是好角色之一吗?

你可以这样写 all:

not all(c in goodCharsEmail for c in newEmail)

...或any:

any(c not in goodCharsEmail for c in newEmail)

这两个是等价的 -- 选择您认为更容易阅读和理解的那个。

理解这些理解表达式的关键可能是理解各部分是如何相互作用的。 c in goodCharsEmail for c in newEmail 表示 evaluate the expression "c in goodCharsEmail" for every c in newEmail.

所以,下面是我将如何重写您发布的验证代码以使其工作:

newEmail = "mail@domain.com" 
goodCharsEmail = "@.abcdefghijkl..." # TODO: more chars, probably
if any(c not in goodCharsEmail for c in newEmail):
    print("bad request")
    quit

最后:不幸的是,电子邮件地址验证比我们大多数人想象的要难得多。如 this blog post 中所述,以下所有(以及更多!)都是 有效 电子邮件地址:

  • "Fred Bloggs"@example.com
  • $A12345@example.com
  • !def!xyz%abc@example.com

如果您只是练习一种新的编程语言,那么您的方法很好。如果您正在为其他人将要使用的某些应用程序或网站编写验证代码,则可能会导致一些挫败感。

玩得开心! :)