後でリストを受け取る引数を持つ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を返します。私はすべての場合の声明を見て、それを使用する方法がわかりません。
あなたの機能はこれに減らすことができます:
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つのオプションは、 itertools
pairwise
レシピ を使用することです。これはサードパーティからも利用できます 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))
実際、コードはnums
がソートされているかどうかをチェックするように減らすことができます。
def checker(nums):
return sorted(nums) == nums
これはあなたが期待することを正確に行います、例えば。
>>> checker([1, 1, 2, 2, 3])
True
>>> checker([1, 1, 2, 2, 1])
False
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