I have a function named checker(nums) that has an argument that will later receive a list. What i want to do with that list is to check if each other element is greater or equal to the previous one.
Example:
I have a list [1, 1, 2, 2, 3]
and i have to check if it fulfills the condition.
Since it does, the function should return True
My code:
def checker(nums):
for x in range(len(nums)):
if x+1<len(nums):
if nums[x] <= nums[x+1] and nums[-1] >= nums[-2]:
return True
This will only run once and return True if the first condition is true. I've seen a statement if all and am unsure of how to use it.
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.()
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
.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:]))
Your code can in fact be reduced to checking if nums
is sorted, e.g.
def checker(nums):
return sorted(nums) == nums
This does exactly what you expect, e.g.
>>> checker([1, 1, 2, 2, 3])
True
>>> checker([1, 1, 2, 2, 1])
False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With