Your function can be reduced to this:
def checker(nums):
return all(i <= j for i, j in zip(nums, nums[1:]))
Note the following:
zip loops through its arguments in parallel, i.e. nums[0] & nums[1] are retrieved, then nums[1] & nums[2] etc.
i <= j performs the actual comparison.
- The generator expression denoted by parentheses
() ensures that each value of the condition, i.e. True or False is extracted one at a time. This is called lazy evaluation.
all simply checks all the values are True. Again, this is lazy. If one of the values extracted lazily from the generator expression is False, it short-circuits and returns False.
Alternatives
To avoid the expense of building a list for the second argument of zip, you can use itertools.islice. This option is particularly useful when your input is an iterator, i.e. it cannot be sliced like a list.
from itertools import islice
def checker(nums):
return all(i <= j for i, j in zip(nums, islice(nums, 1, None)))
Another iterator-friendly option is to use the itertools pairwise recipe, also available via 3rd party more_itertools.pairwise:
# from more_itertools import pairwise # 3rd party library alternative
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
def checker(nums):
return all(i <= j for i, j in pairwise(nums))
Another alternative is to use a functional approach instead of a comprehension:
from operator import le
def checker_functional(nums):
return all(map(le, nums, nums[1:]))