Reason for "All" and "Any" Result on Empty Lists

Reason for all and any result on empty lists

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.

How does all() in python work on empty lists

It's true because for every element in the list, all 0 of them, they all are equal to 2.

You can think of all being implemented as:

def all(my_list, condition):
for a in my_list:
if not condition(a):
return False
return True

Whereas any is:

def any(my_list, condition):
for a in my_list:
if condition(a):
return True
return False

That is to say, all is innocent until proven guilty, and any is guilty until proven innocent.

Why do any and all on an empty list return different things?

Per the documentation of all:

all(iterable)

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

And the documentation for any:

any(iterable)

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

An empty iterable [] is falsey, but it doesn't matter as the return value is just by implementation.


If you're wondering why this happens, it's just a consequence of the implementation. If you look at the equivalent code for all from the documentation:

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

Because of this specific implementation, if the iterable is empty, the for loop is skipped completely as there are no elements. Thus, it returns True. For any, the documentation provides the equivalent code:

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

The reason it returns False for an empty iterable is the same reason all return True. Since there are no elements in the list, the for loop is skipped and it returns False.

This implementation does have a reasoning, since empty set logic makes all return true, see this Math.SE post and this SO answer. all can be thought of as "there are as many true elements as elements". Since an empty set has no true elements and no elements, it returns true because 0 equals 0. any can be thought of as "there's at least one...", and since the set is empty, there's not at least one because there is not even one element. Thus all returns true for an empty set, and any returns false for an empty set.

Why Python built in all function returns True for empty iterables?

This is expressed as "For all X in S, X is true". If S is empty, there are no X. However, the truth statement remains True, because for all X, X was true... there just aren't any X!

Here is a explanation using logic.

Consider two sets A and B where A+B is the union of the two sets.

If any(A+B) = True -> any(A) or any(B) = True but we cannot assert
either any(A)=True or any(B)=True.

If any(A+B) = False -> any(A) = False and any(B) = False.

If all(A+B) = True -> all(A)=True and all(B)=True

if all(A+B) = False -> all(A)=False or all(B)=False but we cannot assert either all(A)=False or all(B)=False.

Now instead of B, let's add the empty set Ø to A. We want to come up
logic such that adding the empty set does not change the values of
all() or any(), since A+Ø=A.

any(A+Ø) = any(A) or any(Ø)

any(Ø) must be False, so that if any(A) is True, any(A+Ø) is True, and
if any(A) is False, any(A+Ø) is False.

all(A+Ø) = all(A) and all(Ø)

if all(A) is True, all(A+Ø) is True. Therefore, all(Ø) is True.

Why do I get an empty list?

I believe you're a little confused on the specific syntax of Python. One thing to note is that while using int works here, it should not be done. In Python int is a built-in type that your code is overwriting. You should also have a loop to actually iterate over every element of the list. Take this code for example:

prices = [2, 50, 70, 30, 555]
new_prices =[]
for price in prices:
if price > 20 and price <= 50:
new_prices.append(price * 0.4)
elif price > 50:
new_prices.append(price * 0.6)
elif price == 5:
new_prices.append(0)

why a number e.g. 2 % a empty set greater than zero is true?

all returns True if it's applied on an empty iterable. set() creates a new empty set, so calling all on any permutation on it, will return True.

Why does Enumerable.All return true for an empty sequence?

It's certainly not a bug. It's behaving exactly as documented:

true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false.

Now you can argue about whether or not it should work that way (it seems fine to me; every element of the sequence conforms to the predicate) but the very first thing to check before you ask whether something is a bug, is the documentation. (It's the first thing to check as soon as a method behaves in a way other than what you expected.)

Why does my method print an empty list?

Adding the same ArrayList instance (referenced by the temp variable) to your reuslt list multiple times is wrong, since your result will contain multiple empty lists (or, more accurately, multiple references to the same empty list) at the end.

You should create a new instance in each iteration instead of clearing the single instance references by temp:

while(true){
levelCount = q.size();
if(levelCount == 0) break;
ArrayList<Integer> temp = new ArrayList<Integer>();
while(levelCount > 0){
TreeNode curr = q.poll();
temp.add(curr.data);
if(curr.left != null){
q.add(curr.left);
}
if(curr.right != null){
q.add(curr.right);
}
levelCount--;
} // end of inner while
result.add(temp);
}

Why don't Array.prototype.some() return true for an empty set?

With .every, you're asking whether all items in a list fulfil a condition. If that list is empty, well, there are no items which do not fulfil the condition. Every item that there is (which is none) fulfils the given condition, so .every is vacuously true.

With .some, you're asking whether any item in a list fulfils a condition. If there are no items, then there's no item to fulfil the condition. So no, nothing in an empty list can fulfil the condition and it's vacuously false.



Related Topics



Leave a reply



Submit