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条回答
Emotional °昔
2楼-- · 2020-01-25 06:53

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.

查看更多
欢心
3楼-- · 2020-01-25 06:53

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.

查看更多
等我变得足够好
4楼-- · 2020-01-25 06:55

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:

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.

查看更多
萌系小妹纸
5楼-- · 2020-01-25 07:05

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.

查看更多
登录 后发表回答