Как использовать оператор IF ALL в Python

У меня есть функция с именем checker (nums), у которой есть аргумент, который позже получит список. То, что я хочу сделать с этим списком, - это проверить, больше ли один или другой элемент предыдущего. Пример: У меня есть список [1, 1, 2, 2, 3], и я должен проверить, выполняет ли он это условие. Так как это так, функция должна возвращать True

Мой код:

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

Это произойдет только один раз и вернет True, если первое условие истинно. Я видел выражение, если все и не знаю, как его использовать.

Ответ 1

Ваша функция может быть уменьшена до этого:

def checker(nums):
    return all(i <= j for i, j in zip(nums, nums[1:]))

Обратите внимание на следующее:

  • zip перебирает свои аргументы параллельно, то есть nums[0] & nums[1], затем nums[1] & nums[2] и т.д.
  • i <= j выполняет фактическое сравнение.
  • Выражение генератора, обозначенное круглыми скобками () гарантирует, что каждое значение условия, т.е. True или False, извлекается по одному за раз. Это называется ленивой оценкой.
  • all просто проверяет, что все значения True. Опять же, это лениво. Если одно из значений, лениво извлеченных из выражения генератора, является False, оно закорачивает и возвращает False.

альтернативы

Чтобы избежать затрат на создание списка для второго аргумента zip, вы можете использовать itertools.islice. Эта опция особенно полезна, когда ваш ввод является итератором, то есть он не может быть разрезан как list.

from itertools import islice

def checker(nums):
    return all(i <= j for i, j in zip(nums, islice(nums, 1, None)))

Другой итератор дружественного варианта заключается в использовании itertools pairwise рецепта, также доступен через 3 партии 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))

Ответ 2

Фактически ваш код можно свести к проверке сортировки nums, например.

def checker(nums):
    return sorted(nums) == nums

Это делает именно то, что вы ожидаете, например

>>> checker([1, 1, 2, 2, 3])
True
>>> checker([1, 1, 2, 2, 1])
False

Ответ 3

Аналогичное решение для @jp_data_analysis с помощью 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

И для научных целей (не рекомендуемый код), вот более функциональный подход

>>> from operator import le
>>> from itertools import starmap
>>> all(starmap(le, windowed(nums, 2)))
True