Python's all(): Check Your Iterables for Truthiness

Python's all(): Check Your Iterables for Truthiness

When programming, you’ll often need to check if all the items in an iterable are truthy. Coding this functionality repeatedly can be annoying and inefficient. Luckily, Python provides the built-in all() function to solve this problem. This function takes an iterable and checks all its items for truth value, which is handy for finding out if those items have a given property or meet a particular condition.

Python’s all() is a powerful tool that can help you write clean, readable, and efficient code in Python.

In this tutorial, you’ll learn how to:

  • Check if all the items in an iterable are truthy by using all()
  • Use all() with different iterable types
  • Combine all() with comprehensions and generator expressions
  • Distinguish between all() and the Boolean and operator

To complement this knowledge, you’ll code several examples that showcase exciting use cases of all() and highlight the many ways to use this function in Python programming.

To understand the topics in this tutorial, you should have basic knowledge of several Python concepts, such as iterable data structures, Boolean types, expressions, operators, list comprehensions, and generator expressions.

Evaluating the Truth Value of Items in Iterables

A pretty common problem in programming is determining if all the items in a list or array are truthy or not. For example, you may have the following list of conditions:

  • 5 > 2
  • 1 == 1
  • 42 < 50

To figure out if these conditions are true, you need to iterate over them and test every condition for truthiness. In this example, you have that 5 > 2 is true, 1 == 1 is true, and 42 < 50 is also true. As a result, you can say that all these conditions are true. If at least one of the conditions were false, then you would say that not all the conditions are true.

Note that as soon as you find a falsy condition, you can stop evaluating conditions because, in that case, you already know the final result: not all are true.

To solve this problem by writing custom Python code, you can use a for loop to iterate over each condition and evaluate it for truthiness. Your loop will iterate until it finds a falsy item, at which point it’ll stop because you already have a result:

Python
>>> def all_true(iterable):
...     for item in iterable:
...         if not item:
...             return False
...     return True
...

This function takes an iterable as an argument. The loop iterates over the input argument while the conditional if statement checks if any item is falsy using the not operator. If an item is falsy, then the function immediately returns False, signaling that not all the items are true. Otherwise, it returns True.

This function is quite generic. It takes an iterable, which means you can pass in a list, tuple, string, dictionary, or any other iterable data structure. To check if the current item is true or false, all_true() uses the not operator to invert the truth value of its operand. In other words, it returns True if its operand evaluates to false and vice versa.

Python’s Boolean operators can evaluate the truth value of expressions and objects, which guarantees that your function can take iterables containing objects, expressions, or both. For example, if you pass in an iterable of Boolean expressions, then not just evaluates the expression and negates the result.

Here’s all_true() in action:

Python
>>> bool_exps = [
...     5 > 2,
...     1 == 1,
...     42 < 50,
... ]
>>> all_true(bool_exps)
True

Because all the expressions in the input iterable are true, not negates the result, and the if code block never runs. In that case, all_true() returns True.

Something similar happens when the input iterable holds Python objects and non-Boolean expressions:

Python
>>> objects = ["Hello!", 42, {}]
>>> all_true(objects)
False

>>> general_expressions = [
...     5 ** 2,
...     42 - 3,
...     int("42")
... ]
>>> all_true(general_expressions)
True

>>> empty = []
>>> all_true(empty)
True

In the first example, the input list contains regular Python objects, including a string, a number, and a dictionary. In this case, all_true() returns False because the dictionary is empty and evaluates to false in Python.

To perform truth value testing on objects, Python has an internal set of rules for objects that evaluate as false:

Any other object evaluates as true when you test it for truthiness in Python.

In the second example, the input list contains general Python expressions, such as math expressions and function calls. In this case, Python first evaluates the expression to get its resulting value, and then it checks that value for truthiness.

The third example highlights an important detail of all_true(). When the input iterable is empty, then the for loop doesn’t run, and the function returns True immediately. This behavior can seem weird at first glance. However, the logic behind it is that if there are no items in the input iterable, then there’s no way to say if any items are falsy. So, the function returns True with empty iterables.

Even though coding all_true() is pretty straightforward in Python, it can be annoying to write this custom function every time you need its functionality. Determining if all the items in an iterable are true is such a common task in programming that Python provides the built-in all() function for the job.

Getting Started With Python’s all()

If you check out the documentation for Python’s all(), then you’ll note that the function is equivalent to the function you coded in the previous section. However, like all built-in functions, all() is a C function and is optimized for performance.

Guido van Rossum proposed the all() and any() functions in an effort to remove functools.reduce() and other functional tools, such as filter() and map(), from Python. However, the Python community wasn’t happy with removing these tools. Even so, all() and any() were added as built-in functions in Python 2.5, with implementations by Raymond Hettinger.

It’s possible to say that Python’s all() performs a reduction or folding operation because it reduces an iterable of items to a single object. However, it’s not a higher-order function because it doesn’t take other functions as arguments to perform its computation. So, you can consider all() a regular predicate or Boolean-valued function.

You can use all() to check if all of the items in an input iterable are true. Because it’s a built-in function, you don’t need to import it. Here’s how it works:

Python
>>> bool_exps = [
...     5 > 2,
...     1 == 1,
...     42 < 50,
... ]
>>> all(bool_exps)
True

>>> objects = ["Hello!", 42, {}]
>>> all(objects)
False

>>> general_exps = [
...     5 ** 2,
...     42 - 3,
...     int("42")
... ]
>>> all(general_exps)
True

>>> empty = []
>>> all(empty)
True

These examples show that all() works the same as your custom function, all_true(). Internally, all() loops over the items in the input iterable, checking their truth values. If it finds a falsy item, then it returns False. Otherwise, it returns True.

If you call all() with an empty iterable, as you did in the final example above, then you get True because there is no falsy item in an empty iterable. Note that all() evaluates the items in the input iterable rather than the iterable itself. See Why Does all() Return True if the Iterable is Empty? for a more philosophical discussion about this.

To summarize the behavior of all(), here’s its table of truth:

Condition Result
All items evaluate as true. True
All items evaluate as false. False
One or more items evaluate as false. False
The input iterable is empty. True

You can run the following calls to all() to confirm the information in this table:

Python
>>> all([True, True, True])
True

>>> all([False, False, False])
False

>>> all([False, True, True])
False

>>> all([])
True

These examples show that all() returns True when all the items in the input iterable are true or when the iterable is empty. Otherwise, the function returns False.

Just like your all_true() function, all() also implements what’s known as short-circuit evaluation. This kind of evaluation means that all() will return as soon as it determines the operation’s final result.

The short-circuiting happens when the function finds a falsy item in the iterable. In that case, there’s no need to evaluate the rest of the items because the function already knows the final result. Note that this type of implementation means that you can get different behaviors when you test conditions with side effects. Consider the following example:

Python
>>> def is_true(value):
...     print("Side effect!")
...     return bool(value)
...

>>> values = [0, 1]

>>> conditions = (is_true(n) for n in values)
>>> all(conditions)
Side effect!
False

>>> conditions = (is_true(n) for n in reversed(values))
>>> all(conditions)
Side effect!
Side effect!
False

The is_true() function takes an object as an argument and returns its truth value. During the function’s execution, a side effect takes place: the function prints something to the screen.

The first instance of conditions holds a generator expression that yields truth values after lazily evaluating each item from an input iterable, which is values in the example. This time, all() only evaluates the function one time because is_true(0) returns False. The side effect runs only once.

Now check out the second instance of conditions. If you reverse the input iterable, then all() evaluates both items because the call to is_true() with 1 as an argument returns True. The side effect runs twice.

This behavior can be a source of subtle issues, so you should avoid evaluating conditions with side effects in your code.

Finally, when it come to using the all() function, you can say that it has at least two generic use cases. You can use all() to check if all items in an iterable:

  1. Evaluate to true
  2. Have a given property or meet a certain condition

In the following section, you’ll learn how to use all() with different iterable types in Python. After that, you’ll learn how to use all() with list comprehensions and generator expressions to solve the second use case listed above.

Using all() With Different Iterable Types

The built-in all() function embraces Python’s duck typing style and accepts different argument types as long as they’re iterable. You can use all() with lists, tuples, strings, dictionaries, sets, and the like.

In all cases, all() does its work as expected, returning True if all the items are truthy and False otherwise. In this section, you’ll code examples using all() with different iterable types.

Sequences

Up to this point, you’ve learned how all() works with Python lists. In this section, you’ll learn that there’s no real difference between lists and other sequence data types, such as tuples, and range objects. All the function needs is for the input object to be iterable.

Here are a few examples of using all() with tuples and range objects:

Python
>>> # With tuples
>>> all((1, 2, 3))
True
>>> all((0, 1, 2, 3))
False
>>> all(())
True
>>> all(tuple())
True

>>> # With range objects
>>> all(range(10))
False
>>> all(range(1, 11))
True
>>> all(range(0))
True

As usual, if all the items in the input iterable are truthy, then you get True. Otherwise, you get False. Empty tuples and ranges produce a True result. In the last example, calling range() with 0 as an argument returns an empty range object, so all() gives you True as a result.

You can also pass tuples containing expressions, Boolean expressions, or Python objects of any type to all(). Go ahead and give it a try!

Dictionaries

Dictionaries are collections of key-value pairs. If you iterate through a dictionary directly, then you’ll loop over its keys automatically. In addition, you can use convenience methods to explicitly iterate dictionaries’ keys, values, and items.

If you pass a dictionary directly to all(), then the function will check the dictionary’s keys automatically:

Python
>>> all({"gold": 1, "silver": 2, "bronze": 3})
True

>>> all({0: "zero", 1: "one", 2: "two"})
False

Because all the keys in the first dictionary are truthy, you get True as a result. In the second dictionary, the first key is 0, which evaluates to false. In this case, you get False back from all().

If you want to get the same result as in the examples above, but with more readable and explicit code, then you can use the .keys() method, which returns all the keys from the underlying dictionary:

Python
>>> medals = {"gold": 1, "silver": 2, "bronze": 3}
>>> all(medals.keys())
True

>>> numbers = {0: "zero", 1: "one", 2: "two"}
>>> all(numbers.keys())
False

With .keys(), you make it explicit that your code calls all() to determine if all the current keys in the input dictionary are truthy.

Another common requirement is that you need to check if all the values in a given dictionary evaluate as true. In that case, you can use .values():

Python
>>> monday_inventory = {"book": 2, "pencil": 5, "eraser": 1}
>>> all(monday_inventory.values())
True

>>> tuesday_inventory = {"book": 2, "pencil": 3, "eraser": 0}
>>> all(tuesday_inventory.values())
False

In these examples, you first check if there’s at least one item in your current inventory of school supplies. On Monday, all your items have at least one unit, so all() returns True. However, on Tuesday, the call to all() returns False because you’ve run out of units in at least one of your supplies, eraser in this case.

Using all() With Comprehensions and Generator Expressions

As you learned earlier, the second use case of Python’s all() is to check if all the items in an iterable have a given property or meet a certain condition. To do this kind of check, you can use all() with a list comprehension or a generator expression as an argument, depending on your needs.

The synergy you get by combining all() with list comprehensions and generator expressions unchains the full power of this function and makes it quite valuable in your day-to-day coding.

One way to leverage this superpower of all() is by using a predicate function that tests for the desired property. This predicate function will be the expression in the list comprehension that you’ll pass as an argument to all(). Here’s the required syntax:

Python
all([predicate(item) for item in iterable])

This list comprehension uses predicate() to test each item in iterable for a given property. Then the call to all() reduces the resulting list to a single True or False value, which tells you if all the items have the property that predicate() defines and tests.

For example, the following code checks if all the values in a sequence are prime numbers:

Python
>>> import math

>>> def is_prime(n):
...     if n <= 1:
...         return False
...     for i in range(2, math.isqrt(n) + 1):
...