Python的任何和所有function如何工作?

我想了解any()all() Python的内置函数是如何工作的。

我试图比较元组,以便如果有任何值是不同的,那么它将返回True ,如果他们都是相同的,它将返回False 。 他们在这种情况下如何工作返回[假,假,假]?

d是一个defaultdict(list)

 print d['Drd2'] # [[1, 5, 0], [1, 6, 0]] print list(zip(*d['Drd2'])) # [(1, 1), (5, 6), (0, 0)] print [any(x) and not all(x) for x in zip(*d['Drd2'])] # [False, False, False] 

据我所知,这应该输出

 # [False, True, False] 

由于(1,1)相同,所以(5,6)不同,(0,0)相同。

为什么所有的元组都评价为False?

你可以粗略地把anyall的逻辑orand运算符分别作为系列。

任何

如果至less有一个元素是Truthy ,任何元素都会返回True 。 阅读关于真值testing。

所有

只有当所有元素都是Truthy时, 所有的才会返回True

真理表

 +-----------------------------------------+---------+---------+ | | any | all | +-----------------------------------------+---------+---------+ | All Truthy values | True | True | +-----------------------------------------+---------+---------+ | All Falsy values | False | False | +-----------------------------------------+---------+---------+ | One Truthy value (all others are Falsy) | True | False | +-----------------------------------------+---------+---------+ | One Falsy value (all others are Truthy) | True | False | +-----------------------------------------+---------+---------+ | Empty Iterable | False | True | +-----------------------------------------+---------+---------+ 

注1:空的迭代案例在官方文档中有解释,像这样

any

如果迭代的任何元素为True则返回True如果迭代是空的,则返回False

由于没有任何元素是真的,所以在这种情况下返回False

all

如果迭代器的所有元素都为真( 或迭代器为空 ), 返回True

由于没有任何元素是假的,在这种情况下它返回True


笔记2:

另外一件重要的事情是要知道结果,它会使执行短路。 优点是,整个迭代不需要消耗。 例如,

 >>> multiples_of_6 = (not (i % 6) for i in range(1, 10)) >>> any(multiples_of_6) True >>> list(multiples_of_6) [False, False, False] 

这里, (not (i % 6) for i in range(1, 10))(not (i % 6) for i in range(1, 10))是一个生成器expression式,如果1和9中的当前数是6的multiples_of_6 ,则返回Trueany迭代multiples_of_6 ,当它满足6 ,它find一个Truthy值,所以它立即返回True ,其余的multiples_of_6不会被迭代。 这是我们在打印list(multiples_of_6)时看到的结果,即89

这个优秀的东西在这个答案中用得非常巧妙。


有了这个基本的理解,如果我们看看你的代码,你可以

 any(x) and not all(x) 

这确保了至less有一个价值是Truthy,但不是全部。 这就是为什么它返回[False, False, False] 。 如果你真的想检查两个数字是否不一样,

 print [x[0] != x[1] for x in zip(*d['Drd2'])] 

Python的anyallfunction如何工作?

anyall元素都是可迭代的,并且如果任何元素和所有(分别)元素都是True则返回True

 >>> any([0, 0.0, False, (), '0']), all([1, 0.0001, True, (False,)]) (True, True) # ^^^-- truthy non-empty string >>> any([0, 0.0, False, (), '']), all([1, 0.0001, True, (False,), {}]) (False, False) # ^^-- falsey 

如果迭代为空,则返回Falseall返回True

 >>> any([]), all([]) (False, True) 

我今天在课堂上向all学生展示了all 。 他们大多对空迭代的返回值感到困惑。 用这种方式解释,导致许多灯泡开启。

快捷行为

他们, any ,都寻找一个条件,让他们停止评估。 我给出的第一个例子要求它们评估整个列表中每个元素的布尔值。

(请注意,列表字面本身并不是懒惰的评估 – 你可以用Iterator来获得 – 但这只是为了说明的目的)。

all

all对元素的检查都是False (所以它可以返回False ),如果它们都不是False ,则返回True

 >>> all([1, 2, 3, 4]) # has to test to the end! True >>> all([0, 1, 2, 3, 4]) # 0 is False in a boolean context! False # ^--stops here! >>> all([]) True # gets to end, so True! 

any

any工作的方式是检查元素为True (所以它可以返回True), then it returns if none of them were True), then it returns False。

 >>> any([0, 0.0, '', (), [], {}]) # has to test to the end! False >>> any([1, 0, 0.0, '', (), [], {}]) # 1 is True in a boolean context! True # ^--stops here! >>> any([]) False # gets to end, so False! 

我想,如果你记住短暂的行为,你会直观地理解他们如何工作,而不必参考真理表。

allany捷径的证据:

首先,创build一个noisy_iterator:

 def noisy_iterator(iterable): for i in iterable: print('yielding ' + repr(i)) yield i 

现在让我们用我们的例子来遍历列表:

 >>> all(noisy_iterator([1, 2, 3, 4])) yielding 1 yielding 2 yielding 3 yielding 4 True >>> all(noisy_iterator([0, 1, 2, 3, 4])) yielding 0 False 

我们可以看到第一个False布尔检查的all站点。

并且在第一个True布尔检查上停止:

 >>> any(noisy_iterator([0, 0.0, '', (), [], {}])) yielding 0 yielding 0.0 yielding '' yielding () yielding [] yielding {} False >>> any(noisy_iterator([1, 0, 0.0, '', (), [], {}])) yielding 1 True 

你所问的代码来自我在这里给出的答案。 它旨在解决比较多个比特arrays的问题 – 即10集合。

当你可以依赖值的“真实性” – 即它们在布尔上下文中的值时, anyall都是有用的。 1为True ,0为False ,这是回答杠杆的方便。 5碰巧也是True ,所以当你将它们混合到可能的input中的时候…好吧。 不起作用。

你可以做这样的事情:

 [len(set(x)) == 1 for x in zip(*d['Drd2'])] 

它缺乏以前的答案的美学(我真的很喜欢any(x) and not all(x) )的外观,但它完成了工作。

 >>> any([False, False, False]) False >>> any([False, True, False]) True >>> all([False, True, True]) False >>> all([True, True, True]) True 
 s = "eFdss" s = list(s) all(i.islower() for i in s ) # FALSE any(i.islower() for i in s ) # TRUE 

我知道这是旧的,但我认为这可能有助于显示这些函数在代码中的样子。 这确实说明了逻辑,比文本或表IMO更好。 实际上,它们是用C而不是纯Python实现的,但是它们是等价的。

 def any(iterable): for item in iterable: if item: return True return False def all(iterable): for item in iterable: if not item: return False return True 

尤其是,你可以看到空的迭代结果只是自然的结果,而不是一个特例。 你也可以看到短路的行为; 实际上是更多的工作, 不要短路。

当Guido van Rossum(Python的创build者) 首先提出添加any()all() ,他只是发布上面的代码片段来解释它们。