web-dev-qa-db-ja.com

PythonでIFALLステートメントを使用する方法

後でリストを受け取る引数を持つ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

これは1回だけ実行され、最初の条件がtrueの場合にTrueを返します。私はすべての場合の声明を見て、それを使用する方法がわかりません。

12
LaurentiuS

あなたの機能はこれに減らすことができます:

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が一度に1つずつ抽出されることを保証します。これは遅延評価と呼ばれます。
  • all すべての値がTrueであることを確認するだけです。繰り返しますが、これは怠惰です。ジェネレータ式から遅延抽出された値の1つがFalseの場合、それは短絡してFalseを返します。

代替案

Zipの2番目の引数のリストを作成する費用を回避するには、 itertools.islice 。このオプションは、入力がイテレータである場合、つまりlistのようにスライスできない場合に特に役立ちます。

from itertools import islice

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

イテレータに適したもう1つのオプションは、 itertoolspairwiseレシピ を使用することです。これはサードパーティからも利用できます 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))
30
jpp

実際、コードはnumsがソートされているかどうかをチェックするように減らすことができます。

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

これはあなたが期待することを正確に行います、例えば。

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

more_itertools.windowed を使用した@jp_data_analysisと同様のソリューション

>>> 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
3
jamylak