我是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:])
—num1
和num2
是nums
的两个连续值,由zip
pingnums
获得。
额外注意:当你需要一个布尔字面值,而不是bool(1)
和bool(0)
,只需使用True
和False
!
你也可以通过将列表按降序排序来简化整个问题,看看它是否与原始列表相同:
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
该模式的简写是any
或all
:
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))