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?
你可以粗略地把any
和all
的逻辑or
和and
运算符分别作为系列。
任何
如果至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
,则返回True
。 any
迭代multiples_of_6
,当它满足6
,它find一个Truthy值,所以它立即返回True
,其余的multiples_of_6
不会被迭代。 这是我们在打印list(multiples_of_6)
时看到的结果,即8
和9
。
这个优秀的东西在这个答案中用得非常巧妙。
有了这个基本的理解,如果我们看看你的代码,你可以
any(x) and not all(x)
这确保了至less有一个价值是Truthy,但不是全部。 这就是为什么它返回[False, False, False]
。 如果你真的想检查两个数字是否不一样,
print [x[0] != x[1] for x in zip(*d['Drd2'])]
Python的
any
和all
function如何工作?
any
和all
元素都是可迭代的,并且如果任何元素和所有(分别)元素都是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
如果迭代为空,则返回False
, all
返回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!
我想,如果你记住短暂的行为,你会直观地理解他们如何工作,而不必参考真理表。
all
和any
捷径的证据:
首先,创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的问题 – 即1
和0
集合。
当你可以依赖值的“真实性” – 即它们在布尔上下文中的值时, any
和all
都是有用的。 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()
,他只是发布上面的代码片段来解释它们。