Python has many hidden gems that make writing code much cleaner and idiomatic. Today we will take a look at two built-in functions: any() and all().

(Well, technically they are callable classes, but the docs call them functions so we will go with that.)

Built-in functions are those that automatically available when you start Python - you don't need to import any module to use them.

Let us start with a problem

Given a list ensure that it is sorted, either all ascending or all descending.

A straightforward way is to take each pair of elements and check that in all pairs the prior element is less than or equal to the next one.

Comparing each element with the prior element requires iterating the list two elements at a time. We can easily do this using the pairwise iteration helper from itertools.

ascending = None
for prev, current in pairwise(lst):
    if prev > current:
        ascending = False
        break
else:
    ascending = True

This code isn't terrible, but it's very messy. We need to loop the list, need to implement the early break out of the loop, maintain a flag and so on. There are a lot of implementation details that distract from the intent of the code. (And yes, in case you never used it before, Python's for loop has an else option)

Here is a better way.

The all() built-in does all that for us. Given a list of booleans, it will return True if all of them are True. If any one is False, then all() will return False.

Here is the same code written using all()

ascending = all(prev <= current for prev, current in pairwise(lst))

We don't need to implement the looping, the early exit from the loop or maintaining the flag. Just call the function and get the value! It's these simple things that make coding in Python so much nicer.

any() works the same way, except it returns True if any one of the elements is True and False otherwise.

ascending = all(prev <= current for prev, current in pairwise(lst))
descending = all(prev >= current for prev, current in pairwise(lst))
is_sorted = any([ascending, descending])

# that last line could be 'ascending or descending' but 
# any() can extend to dynamic list of conditions determined at runtime

Now that's beautiful and pythonic code.

Did you like this article?

If you liked this article, consider subscribing to this site. Subscribing is free.

Why subscribe? Here are three reasons:

  1. You will get every new article as an email in your inbox, so you never miss an article
  2. You will be able to comment on all the posts, ask questions, etc
  3. Once in a while, I will be posting conference talk slides, longer form articles (such as this one), and other content as subscriber-only

Tagged in: