我怎么知道一个列表是递减的?(Python)



我是python的新手,我必须为课堂做一个练习。这个练习要求我写一个函数,告诉我给定的列表是按递减顺序排列的还是按非递减顺序排列的(返回真或假)。我尝试了以下代码:

def no_decreasing(list):
for num in len(list):
if list[num] <= list[num+1]:
check = bool(1)
else:
check = bool(0)
break
return check

返回错误"int"对象在第二行是不可迭代的,有人知道为什么吗?

注意:不要使用list作为参数名(它是内置类型),使用其他名称。我将使用nums作为列表参数的位置,而不是list

表达式for num in len(nums)不起作用,因为len(nums)是单个整型。您需要的是for num in nums(它将遍历nums中的每个数字,或者for index in len(range(nums))(它将遍历每个有效索引到nums)。

其他选项:

  • for i, num in enumerate(nums)i为索引,num为值。
  • for num1, num2 in zip(nums, nums[1:])num1num2nums的两个连续值,由zippingnums获得。

额外注意:当你需要一个布尔字面值,而不是bool(1)bool(0),只需使用TrueFalse!

你也可以通过将列表按降序排序来简化整个问题,看看它是否与原始列表相同:

def is_decreasing(nums):
return nums == sorted(nums, reverse=True)

你要对索引进行迭代,所以

for i in range(len(lst)):  # never use "list" as a variable name

或者

for i in range(len(lst)-1):  # to avoid an index error for its right neighbor

是合适的。但是,更好的方法是使用zip

def non_decreasing(lst):
for a, b in zip(lst, lst[1:]):
if b < a:
return False
return True

该模式的简写是anyall:

def non_decreasing(lst):
return all(a <= b for a, b in zip(lst, lst[1:]))
# return not any(b < a for a, b in zip(lst, lst[1:]))

您试图在for循环中获得索引,但是您犯了一个语义错误:

for num in len(list):
# This does not work. It can not iterate through an integer.

len()函数返回一个整数。你基本上说的是for num in 10,如果列表有10个数字。

您需要的是range函数:

for num in range(0, len(list)):

将从num=0循环到num=0+len(list)-1

使用if list[num] <= list[num+1]:时要小心,因为前面的方法会使行搜索的索引大于数组大小。因此,您可以这样修改代码:

for num in range(0, len(list)-1):

注::还有其他方法可以解决这个问题,但由于这是一个课堂练习,我集中解决你在迭代整数时遇到的问题。

其他人指出使用zip(lst, lst[1:])。但是,对于大列表来说,这是不可取的,因为在zip生成for循环使用的成对迭代器之前,您必须首先复制lst(减去第一个元素)。

相反,使用两个单独的迭代器,在传递给zip之前先推进第二个迭代器。

def no_decreasing(lst):
i1 = iter(lst)
i2 = iter(lst)
next(i2)
return all(a >= b for a, b in zip(i1, i2))
# Or you can use map
# return all(map(operator.ge, i1, i2))