我有一个名为 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。
我看过一个声明,但不确定如何使用它。
您的功能可以简化为:
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
执行实际比较。
- generator expression用括号表示
()
确保条件的每个值,即 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
recipe ,也可通过第三方获得 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))
另一种替代方法是使用功能方法而不是理解:
from operator import le
def checker_functional(nums):
return all(map(le, nums, nums[1:]))