How to use the IF ALL statement in Python
--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 5 Looping
--
Chapters
00:00 How To Use The If All Statement In Python
00:41 Accepted Answer Score 32
02:13 Answer 2 Score 9
02:29 Answer 3 Score 3
02:51 Thank you
--
Full question
https://stackoverflow.com/questions/4886...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #list #sorting #ifstatement #conditionalstatements
#avk47
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 5 Looping
--
Chapters
00:00 How To Use The If All Statement In Python
00:41 Accepted Answer Score 32
02:13 Answer 2 Score 9
02:29 Answer 3 Score 3
02:51 Thank you
--
Full question
https://stackoverflow.com/questions/4886...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #list #sorting #ifstatement #conditionalstatements
#avk47
ACCEPTED ANSWER
Score 32
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:
ziploops through its arguments in parallel, i.e.nums[0]&nums[1]are retrieved, thennums[1]&nums[2]etc.i <= jperforms the actual comparison.- The generator expression denoted by parentheses
()ensures that each value of the condition, i.e.TrueorFalseis extracted one at a time. This is called lazy evaluation. allsimply checks all the values areTrue. Again, this is lazy. If one of the values extracted lazily from the generator expression isFalse, it short-circuits and returnsFalse.
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:]))
ANSWER 2
Score 9
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
ANSWER 3
Score 3
Similar solution to @jp_data_analysis using more_itertools.windowed
>>> from more_itertools import windowed
>>> nums = [1, 1, 2, 2, 3]
>>> all(i <= j for i, j in windowed(nums, 2))
True
And for scientific purposes (not recommended code), here is a more functional approach
>>> from operator import le
>>> from itertools import starmap
>>> all(starmap(le, windowed(nums, 2)))
True