主要问题是您写了for i in range(len(xs)):,然后尝试访问xs[i+1]。这势必会在循环的最后一次迭代中引发异常IndexError: list index out of range。
您的代码的第二个问题是else: True 或else: False 部分,它们什么都不做。您可能忘记了关键字return。就目前而言,您的代码相当于:
import operator
def sorted (a, xs):
'''a is the operator, xs is a list'''
if a == operator.gt:
for i in range(len(xs)):
if xs[i] < xs[i+1]:
return False
当i == len(xs)-1 和i+1 为1 太大时,将在循环的最后一次迭代中引发异常。
你是否会得到异常IndexError: list index out of range取决于for循环是否有机会进行它的最后一次迭代,或者函数是否会在return的最后一次迭代之前for -循环。
另一个问题是你调用了你的函数sorted,它已经是python中内置函数的名称。重复使用该名称将导致混淆和可能的错误。由于您的函数不返回排序列表,而是测试列表是否排序,因此我建议将其称为 is_sorted。
同时解决这两个问题:
- 删除
else 分支;
- 添加
return True 在与for关键字相同的缩进级别;
- 将
range(len(xs)) 替换为range(len(xs)-1)。
您了解此处需要-1 吗?想象一下,如果您的列表有 3 个元素。你需要多少次比较才能检查它是否排序?您需要将第一个元素与第二个元素进行比较;然后是第二个和第三个;就是这样。 3 个元素只有 2 次比较。如果省略-1,您将尝试将第三个元素与虚构的第四个元素进行比较,python 解释器会抱怨并引发IndexError: list index out of range。
最终代码:
import operator
def is_sorted (a, xs):
'''a is the operator, xs is a list'''
if a == operator.gt:
for i in range(len(xs)-1):
if xs[i] < xs[i+1]:
return False
return True
遵循python约定:可选参数reverse
比较参数a 和operator.gt 有点笨拙,因为您编写的函数无论如何都不适用于自定义运算符。我建议遵循python builtins sorted and list.sort() 的约定,它使用可选参数reverse 默认为False。
代码:
def is_sorted(xs, reverse=False):
if not reverse:
for i in range(len(xs)-1):
if xs[i] > xs[i+1]:
return False
return True
else:
for i in range(len(xs)-1):
if xs[i] < xs[i+1]:
return False
return True
进一步的改进建议:
- 添加可选参数
key,如python内置sorted和list.sort;
- 让用户给你一个比较运算符,并直接使用该运算符而不是
< 或>
def is_sorted(xs):
return all(xs[i] <= xs[i+1] for i in range(len(xs)-1))
def is_sorted(xs):
return not any(xs[i] > xs[i+1] for i in range(len(xs)-1))