Python’s all(): Built-in Function for Searching Among the Many

Python's all() function is so powerful that it was declared part of the built-in library. Understanding how to use this chaining conditional function can make your code more concise, flexible, and *pythonic* to boot!
python all function overcoded

The Python all() function is a built-in that evaluates an entire collection for truthiness. It can be used in static syntax or more dynamic implementations involving such features as list comprehension and generators. It can be used in combination with other language features to built powerful and succinct conditional statements.

The all() function’s possible use-cases are limited by little more than a developer’s imagination and in this article, I’ll showcase some basic usage, a few advanced cases, and hopefully illustrate why Every Python programmer should become intimately familiar with the built-in all() function.

TL;DR – The all() function tests an entire collection for conditions evaluating to True

# Have a collection of integers
>>> nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Check all items are integers
>>> all(int(x) for x in nums)

# That's a bingo
True

Basic Usage

Python’s all function is used to check all members in a collection for truthiness. There are many iterable types in Python including lists, dictionaries, sets, generators, and even strings. Each of these data types can be used along with the all function. It can be compared to the more semantic for all in a list, check each is True. Let’s consider some canonical use cases.

Case 1: Basic Truth Testing

# Create a list
l = [0, 1, 2, 3, 4, 5]

all(l)
>>> False

This example demonstrates the core behavior of the all function: testing all items in an iterable for a True or False value. In this case, the failing member is the first element; the 0 (equivalent of False). For example:

# Check the numerical value of False
>>> 0 == False

True

# Check the numerical value of True
>>> 1 == True

True

# Check for other values of True
>>> 1 == True and 2 == True and 3 == True and 4 == True and 5 == True

False

# Remove the 0 element from list, use all
>>> all([1, 2, 3, 4, 5)]

True

# Check an empty list
>>> all([])

True

These examples may seem mildly infuriating. That is the sweet feeling of learning something new! Per the official Python documentation, the all function will; Return True if all elements of the iterable are true (or if the iterable is empty). I find this statement confusing and would re-phrase it as such:

Returns True if all elements of the iterable are not False. The statements x is not False and x is True are equivalent logically but the former offers better clarity in this context.

With this in mind, let’s reconsider the first example and why it evaluated to False using the all function.

# Create a list l = [0, 1, 2, 3, 4, 5]
>>> all(l)

False

# Create another list 
l_2 = [1, 2, 3, 4, 5]
>>> all(l_2)

True

The 0 element of the first list is causing the all statement to evaluate to False. This is because the numerical value 0 is equivalent to False under-the-hood. Read this article for more on how Python (and other programming languages) represent numbers internally. Removing the 0 leaves only non-zero elements—which evaluate to not-False.

The entirety of any logic-based function is always tough to grasp. These examples are intended to better illustrate the nuances of the all function such that the following, more advanced cases, can be better understood.

Other Examples

I find most applications for my use of the all function to be somewhat dynamic. In most cases, I’m using comprehension syntax to check large numbers of membership as a conditional statement for executing some other logic. In other words, taking advantage of Python’s succinct syntax! Consider the following example:

from string import printable

# Check if all letters of a string are in the 
# string.printable variable (ASCII characters)
if all(x in printable for x in 'hello, world!'):
    print("All Letters are ASCII!")
else:
    print("Non-ASCII letters found!")

# The result:
All letters as ASCII!

In this example, the all() function is used to check that every letter in the string "hello, world!" is found within the string.printable variable.

Note: The string.printable variable is equal to the following string (minus a few whitespaces):

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Check out this ASCII table for more information on these types of character sets. This example showcases a basic use-case of the all() function that one might encounter in the wild. Testing for multiple membership conditions is a powerful way to make decisions with complex or dynamic data. Let’s consider a more complex example.

Combining Statements

Here we’ll see an example where the all() function is used in combination with another one of the Python builtins; the any() function. Using a very contrived set of data, we’ll check that one of the color values is present in all of the data entries’ key values:

# Define a set of values
colors = ['red', 'blue', 'green']
numbers = [1, 2, 3]

# Generate some random data
>>> data = {
    choice(colors) + "-" + choice(colors): choice(numbers) * choice(numbers)
    for x in range(10)
}
{'blue-blue': 3, 'blue-red': 2, 'red-blue': 2, 'green-green': 6, 'red-green': 1, 'blue-green': 2}

# Check that ALL members in 'data' contain ANY member of 'colors'
>>> all(any(x in y for y in data.keys()) for x in colors)
True

This exemplifies not only how the all() function can be used dynamically but also the joys of using Python comprehension statements. Apologies for the bizarre construction of the data object—I was having a shortfall of imagination!

Note: Check out this article for a deeper look at Python’s any() built-in function.

Extracting Items into Another Collection

Python’s all() method can be used to extract subsets from collections where conditional membership is needed. Consider the following [very contrived] example:

# Create some random collection of numbers
num_pairs = [(1, 3), (2, 4), (3, 6, 9), (1, 2, 3, 4), (4, 6, 8)]

# Extract any pair of numbers where only even numbers are present
evens = [x for x in num_pairs if all(n % 2 == 0 for n in x)]

>>> evens
 
# Results in sub-sets containing
# only all-even values
[(2, 4), (4, 6, 8)]

This showcases the use of the all() function to check each tuple in the collection for only even values. For any tuple containing no non-even values (odd == not False) Python’s comprehension syntax will collect that item into the new evens collection.

Advanced Considerations

There are some possible performance issues when testing large collections for membership. In the following example, I’ll use the all() function to check a list of 100,000,000 million randomly generated 1’s and 0’s to ensure all members are integer values. Before I check, however, I’ll add a single non-integer 'z' character to the end of the collection.

# Create a list 100MMK 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))

# Add the letter "z" to the end
nums.append('z')

# Test that all members are numerical
import timeit
>>> timeit.timeit(lambda: all(type(x) == int for x in nums))

# Total Execution Time
5.397376900000005

This code does the following:

  1. Creates a list of 100,000,000 1’s and 0’s in random order
  2. Append a single 'z' character to the end
  3. Test that all items in the list are integer values

Note the total runtime of this code is ~5.40 seconds with a ‘z’ character at the end of the sequence. This time reflects the all() functions need to iterate over every single element before it can be sure all are integers.

Now imagine that the 'z' character was placed at the beginning. Without proper checks in place, one might find themselves iterating over an entire collection before determining truthiness. For example, counting the total number occurrences of a non-integer item and comparing that to 0.

The developers of Python are clever. The moment a condition evaluates to a non-Truthy value the all() function will shortcircuit rather than evaluating completely. Consider the above example, this time with the character 'z' added to the start of the collection.

# Create a list 100MM 1's or 0's, chosen randomly
import random
nums = list(random.choice([0, 1]) for x in range(10**8))

# Add the letter "z" to the start
nums.insert(0, 'z')

# Test that all members are numerical
import timeit
timeit.timeit(lambda: all(type(x) == int for x in nums), number=1)

# A reeaaly small value
2.600000001962144e-06

Do you need to know this to enjoy the all() function? Absolutely not. I find a better understanding of how functions were developed, especially the consideration made for performance issues, helps clarify their application. I’m a nerd like that.

Final Thoughts

The Python all() function is one of the most useful tools of the language in my opinion. Its ability to batch-test truthiness comes in handy on a daily basis in my experience. Other languages and lambda their way into similar utility but few offer the out-of-the-box, performant, native syntax that Python does. Combined with generators, comprehensions, and a little imagination—the all() function can make one feel really smart (until code review time, anyway!)

alpharithms discord banner 1
Zαck West
Entrepreneur, programmer, designer, and lifelong learner. Can be found taking notes from Mother Nature when not hammering away at the keyboard.