Reason for “all” and “any” result on empty lists

2020-01-25 06:30发布

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.)

标签: python logic
10条回答
手持菜刀,她持情操
2楼-- · 2020-01-25 06:44

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. :)

查看更多
趁早两清
3楼-- · 2020-01-25 06:44
  • all([]) == True: zero out of zero - check
  • any([]) == False: anyone? nobody - fail
查看更多
4楼-- · 2020-01-25 06:45

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.
查看更多
淡お忘
5楼-- · 2020-01-25 06:51

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
查看更多
孤傲高冷的网名
6楼-- · 2020-01-25 06:52

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

查看更多
Deceive 欺骗
7楼-- · 2020-01-25 06:52

For general interest, here's the blog post in which GvR proposes any/all with a sample implementation like gnibbler's and references quanifiers in ABC.

查看更多
登录 后发表回答