“全部”的原因是:和“任何”结果为空列表

发布于 2024-09-10 08:18:22 字数 405 浏览 0 评论 0原文

在 Python 中,内置函数 allany 返回 TrueFalse 分别表示空迭代。我意识到,如果反过来的话,这个问题仍然可以问。但我想知道为什么选择这种特定行为。它是任意的吗?是否同样容易出现相反的情况,或者是否有根本原因?

(我问的原因很简单,因为我从来不记得哪个是哪个,如果我知道其背后的基本原理,那么我可能会知道。还有,好奇心。)

In Python, the built-in functions all and any return True and False respectively for empty iterables. I realise that if it were the other way around, this question could still be asked. But I'd like to know why that specific behaviour was chosen. Was it arbitrary, ie. could it just as easily have been the other way, or is there an underlying reason?

(The reason I ask is simply because I never remember which is which, and if I knew the rationale behind it then I might. Also, curiosity.)

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

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

发布评论

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

评论(8

勿挽旧人 2024-09-17 08:18:22

打个比方怎么样……

你有一个袜子抽屉,但目前是空的。里面有黑袜子吗?不——你根本没有袜子,所以你当然没有黑色的袜子。显然 any([]) 必须返回 false - 如果它返回 true 这将是违反直觉的。

all([]) 的情况稍微困难一些。请参阅关于空洞的真相的维基百科文章。另一个类比:如果一个房间里没有人,那么那个房间里的每个人都会说法语。

数学上 all([]) 可以写成:

xA, Q(x),其中集合 A 为空。

关于空洞的陈述是否应该被视为真实存在相当多的争论,但从逻辑的角度来看,它是最有意义的:

所有空洞真实的陈述都是真实的主要论点如下:正如逻辑的文章中所解释的条件句,命题逻辑的公理意味着如果 P 为假,则 P ⇒ Q 为真。也就是说,如果我们接受这些公理,我们就必须接受空洞真实的陈述确实是真实的。

还来自文章:

似乎没有直接理由选择 true;只是如果我们不这样做,事情就会在我们面前爆炸。

在 Python 中定义一个“空洞为真”的语句返回 false 会违反最小惊讶原则

How about some analogies...

You have a sock drawer, but it is currently empty. Does it contain any black sock? No - you don't have any socks at all so you certainly don't have a black one. Clearly any([]) must return false - if it returned true this would be counter-intuitive.

The case for all([]) is slightly more difficult. See the Wikipedia article on vacuous truth. Another analogy: If there are no people in a room then everyone in that room can speak French.

Mathematically all([]) can be written:

xA, Q(x), where the set A is empty.

There is considerable debate about whether vacuous statements should be considered true or not, but from a logical viewpoint it makes the most sense:

The main argument that all vacuously true statements are true is as follows: As explained in the article on logical conditionals, the axioms of propositional logic entail that if P is false, then P ⇒ Q is true. That is, if we accept those axioms, we must accept that vacuously true statements are indeed true.

Also from the article:

There seems to be no direct reason to pick true; it’s just that things blow up in our face if we don’t.

Defining a "vacuously true" statement to return false in Python would violate the principle of least astonishment.

原来分手还会想你 2024-09-17 08:18:22

any 的一个属性是它的递归定义,

any([x,y,z,...]) == (x or any([y,z,...]))

这意味着

x == any([x]) == (x or any([]))

当且仅当 any([]) 定义为是假的。与全部类似。

One property of any is its recursive definition

any([x,y,z,...]) == (x or any([y,z,...]))

That means

x == any([x]) == (x or any([]))

The equality is correct for any x if and only if any([]) is defined to be False. Similar for all.

豆芽 2024-09-17 08:18:22

我相信 all([])==True 通常更难掌握,因此这里有一系列示例,我认为这种行为显然是正确的:

  • 如果 <电影中的所有对话都带有字幕。没有对话的电影仍然适合听力障碍者。
  • 当里面所有的灯都关掉时,无窗的房间就会变得黑暗。当里面没有灯的时候,里面一片漆黑。
  • 当您的所有液体都装在 100 毫升的瓶子中时,您就可以通过机场安检。如果您没有携带液体,您仍然可以通过安检。
  • 如果包中的所有物品都比狭槽窄,则您可以将软包放入狭窄的狭槽中。如果袋子是空的,它仍然可以穿过插槽。
  • 当任务的所有先决条件都满足时,就可以开始任务了。如果任务没有先决条件,则它已准备好开始。

I believe all([])==True is generally harder to grasp, so here are a collection of examples where I think that behaviour is obviously correct:

  • A movie is suitable for the hard of hearing if all the dialog in the film is captioned. A movie without dialog is still suitable for the hard of hearing.
  • A windowless room is dark when all the lights inside are turned off. When there are no lights inside, it is dark.
  • You can pass through airport security when all your liquids are contained in 100ml bottles. If you have no liquids you can still pass through security.
  • You can fit a soft bag through a narrow slot if all the items in the bag are narrower than the slot. If the bag is empty, it still fits through the slot.
  • A task is ready to start when all its prerequisites have been met. If a task has no prerequisites, it's ready to start.
旧城烟雨 2024-09-17 08:18:22

我认为它们是这样实现的,但

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

def any(seq):
    for item in seq:
        if item:
            return True
    return False

不确定它们是这样实现的

I think of them as being implemented this way

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

def any(seq):
    for item in seq:
        if item:
            return True
    return False

not sure they are implemented that way though

八巷 2024-09-17 08:18:22

Perl 6 还认为空列表上的 all()any() 应该作为其各自归约运算符的合理基本情况,因此 all () 为 true,any() 为 false。

也就是说all(a, b, c)相当于[&] a, b, c,相当于a & b& c (减少“连接与”运算符,但您可以忽略连接并将其视为本文的逻辑与),并且 any(a, b, c) 相当于[|] a, b, c,相当于a |乙| c (减少“连接或”运算符——同样,您可以假装它与逻辑或相同,而不会遗漏任何内容)。

任何可以应用归约的运算符在归约 0 项时都需要有一个定义的行为,通常这是通过拥有一个自然的单位元素来完成的——例如,[+]()(归约)跨零项的加法)为 0,因为 0 是加法恒等式;向任何表达式添加零都会使其保持不变。 [*]() 同样是 1,因为 1 是乘法恒等式。我们已经说过,all 相当于 [&]any 相当于 [|] -- 好吧,真理是-恒等式,虚假是-恒等式-- x 和 True 是 x,并且 >x 或 False 是 x。这使得 all() 不可避免地应该为 true,而 any() 应该为 false。

从一个完全不同(但实用)的角度来看,any 是一个闩锁,它从 false 开始,只要看到 true 就变为 true; all 是一个锁存器,它从 true 开始,每当看到 false 时就变为 false。不给他们任何参数意味着他们没有机会改变状态,所以你只是问他们的“默认”状态是什么。 :)

Perl 6 also takes the position that all() and any() on empty lists should serve as sane base-cases for their respective reduction operators, and therefore all() is true and any() is false.

That is to say, all(a, b, c) is equivalent to [&] a, b, c, which is equivalent to a & b & c (reduction on the "junctive and" operator, but you can ignore junctions and consider it a logical and for this post), and any(a, b, c) is equivalent to [|] a, b, c, which is equivalent to a | b | c (reduction on the "junctive or" operator -- again, you can pretend it's the same as logical or without missing anything).

Any operator which can have reduction applied to it needs to have a defined behavior when reducing 0 terms, and usually this is done by having a natural identity element -- for instance, [+]() (reduction of addition across zero terms) is 0 because 0 is the additive identity; adding zero to any expression leaves it unchanged. [*]() is likewise 1 because 1 is the multiplicative identity. We've already said that all is equivalent to [&] and any is equivalent to [|] -- well, truth is the and-identity, and falsity is the or-identity -- x and True is x, and x or False is x. This makes it inevitable that all() should be true and any() should be false.

To put it in an entirely different (but practical) perspective, any is a latch that starts off false and becomes true whenever it sees something true; all is a latch that starts off true and becomes false whenever it sees something false. Giving them no arguments means giving them no chance to change state, so you're simply asking them what their "default" state is. :)

我不会写诗 2024-09-17 08:18:22

anyall 在 python 中与其他地方具有相同的含义:

  • 如果至少有一个为 true,则 any 为 true
  • all 如果至少有一个不为真则不为真

any and all have the same meaning in python as everywhere else:

  • any is true if at least one is true
  • all is not true if at least one is not true
装迷糊 2024-09-17 08:18:22

这实际上更像是一个注释,但是注释中的代码效果不太好。

除了解释 any()all() 工作原理的其他逻辑基础之外,它们还必须具有相反的“基本”情况,以便这种关系成立:

all(x for x in iterable) == not any(not x for x in iterable)

如果 iterable 的长度为零,则上述内容仍然应该成立。因此,

all(x for x in []) == not any(not x for x in [])

这相当于

all([]) == not any([])

如果 any([]) 是正确的,那将是非常令人惊讶的。

This is really more of a comment, but code in comments doesn't work very well.

In addition to the other logical bases for why any() and all() work as they do, they have to have opposite "base" cases so that this relationship holds true:

all(x for x in iterable) == not any(not x for x in iterable)

If iterable is zero-length, the above still should hold true. Therefore

all(x for x in []) == not any(not x for x in [])

which is equivalent to

all([]) == not any([])

And it would be very surprising if any([]) were the one that is true.

稀香 2024-09-17 08:18:22

官方原因尚不清楚,但从文档来看(确认@John La Rooy 的帖子):

全部(可迭代)

如果可迭代的所有元素都为 true(或者可迭代为空),则返回 True
相当于:

 def all(可迭代):
       对于可迭代中的元素:
           如果不是元素:
               返回错误
      返回真

任何(可迭代)

如果可迭代的任何元素为 true,则返回 True。如果可迭代对象为空,则返回 False。相当于:

 def any(可迭代):
       对于可迭代中的元素:
           如果元素:
               返回真
       返回错误

另请参阅 CPython 实现和注释

The official reason is unclear, but from the docs (confirming @John La Rooy's post):

all(iterable)

Return True if all elements of the iterable are true (or if the iterable is empty).
Equivalent to:

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

any(iterable)

Return True if any element of the iterable is true. If the iterable is empty, return False. Equivalent to:

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

See also the CPython-implementation and comments.

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