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:
- Creates a list of 100,000,000 1’s and 0’s in random order
- Append a single
'z'
character to the end - 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!)