这个输入与Python的'any'函数如何配合使用?

132

在 Python 文档页面上,any 函数的等效代码如下:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

如果我以这种形式调用函数,该函数如何知道我想要测试哪个元素?

any(x > 0 for x in list)

从这个函数定义中,我能看到的只有我传递了一个可迭代对象。那么for循环是如何知道我要找的内容是> 0呢?


这个问题实际上不是关于 any 的,而是关于示例代码中 传递给 any 的参数,它是一个 生成器表达式。因此,我将其关闭为生成器表达式的参考问题的重复。如果您真正想了解有关 any 的信息,请参阅 https://dev59.com/RmIk5IYBdhLWcg3wUsrv 获取规范答案。 - Karl Knechtel
5个回答

189

如果你使用 any(lst),你会看到 lst 是一个可迭代对象,它是一些项目的列表。如果它包含了 [0, False, '', 0.0, [], {}, None](这些值都被认为是布尔值为 False 的值),那么 any(lst) 将返回 False。如果 lst 同时包含以下任意一个值 [-1, True, "X", 0.00001](所有这些值都被认为是布尔值为 True 的值),那么 any(lst) 将返回 True

在你发布的代码中,x > 0 for x in lst 是另一种类型的可迭代对象,称为生成器表达式。在 Python 中添加生成器表达式之前,你会创建一个列表推导,它看起来非常相似,但使用方括号 [] 括起来:[x > 0 for x in lst]。从包含 [-1, -2, 10, -4, 20]lst 中,你将得到这个推导列表[False, False, True, False, True]。这个内部值将被传递给 any 函数,因为至少有一个 True 值,所以它将返回 True

但是有了生成器表达式,Python就不再需要创建那个由True(s)False(s)组成的内部列表,这些值将在any函数通过逐个生成器表达式所生成的值迭代时被生成。而且,由于any具有短路特性,它会在第一次遇到True值时停止迭代。如果你使用类似于lst=range(-1,int(1e9))(或者如果你使用Python2.x,则使用xrange)的东西创建了lst,这将非常方便。即使这个表达式将生成超过十亿个条目,当它到达1时,any只需一直到第三个条目,因为它对于x>0评估为True,所以any可以返回True
如果你使用列表推导式来实现,Python首先必须在内存中创建包含十亿个元素的列表,然后将其传递给any。但是通过使用生成器表达式,你可以让Python的内置函数如anyall尽早跳出循环,即一旦看到TrueFalse值就停止。

29
值得一提的是,any(x > 0 for x in list)只是any((x > 0 for x in list))的语法糖。 - georg
3
你应该将 None 添加到布尔值为 False 的元素列表中。 - Alok Mysore
3
续@georg所说,这种语法糖不只适用于 anydef b(x): return x; print b(x > 1 for x in xs) # prints <generator object .. - industryworker3595112
@georg 谢谢您的澄清。当我测试带有任何括号的代码时,这是一个让我感到困惑的非常重要的点。 - MasayoMusic
not set() 似乎也会被评估为 True,所以我也会将其添加到列表中。实际上这不是一个全面的列表,但在此处添加它是没有意义的,最好链接到它 - https://dev59.com/laHia4cB1Zd3GeqPRlJ9 - Szymon

50
>>> names = ['King', 'Queen', 'Joker']
>>> any(n in 'King and john' for n in names)
True

>>> all(n in 'King and Queen' for n in names)
False

它只是将几行代码压缩成一行。 你不必编写冗长的代码,例如:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False

23

(x > 0 for x in list) 在该函数调用中创建了一个生成器表达式。

>>> nums = [1, 2, -1, 9, -5]
>>> genexp = (x > 0 for x in nums)
>>> for x in genexp:
        print x


True
True
False
True
False

当遇到第一个计算结果为 True 的对象时,any 函数会短路并返回。


9

这是因为可迭代对象是

(x > 0 for x in list)

请注意,x > 0返回的是TrueFalse,因此您有一个布尔值可迭代对象。

7

简单来说,any()的作用是:根据条件在列表中遇到任何一个满足条件的值,就返回true,否则返回false。

list = [2,-3,-4,5,6]

a = any(x>0 for x in lst)

print a:
True


list = [2,3,4,5,6,7]

a = any(x<0 for x in lst)

print a:
False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接