1.2 在一个任意的列表中查找最大值
观察程序清单1-1展示的存在缺陷的Python实现,它试图在一个至少包含1个值的任意列表中查找最大值。它所采用的方法是把A
中的每个值与my_max
进行比较,如果发现一个更大的值就更新my_max
。
程序清单1-1 在列表中查找最大值的算法的一种存在缺陷的实现
def flawed(A):
my_max = 0 ❶
for v in A: ❷
if my_max < v:
my_max = v ❸
return my_max
❶ my_max
是保存最大值的变量,在这里my_max
被初始化为0。
❷ for
循环定义了变量v
,用于对A
中的每个元素进行迭代。对v
的每个值均执行一次if
语句。
❸ 如果v
更大,就更新my_max
。
这个实现的核心是对两个数进行比较以确定其中一个值是否小于另一个值的小于操作。在图1-3中,当v
依次从A
中取连续的值时,我们可以看到my_max
被更新了3次,从而确定了A
中的最大值。flawed()
函数用于确定A
中的最大值,调用了6次小于操作,对每个值各调用1次。在一个规模为N的问题实例中,flawed()
调用N次小于操作。
图1-3 flawed()
的执行示意
这个实现存在缺陷,因为它假设A
中至少有一个值大于0。计算flawed([–5,–3,–11])
时将返回0,这是不正确的。一种常见的弥补方法是把my_max
初始化为可能出现的最小值,例如my_max =float('-inf')
。这个方法仍然存在缺陷,因为如果A
是空列表[]
,它就会返回这个值。现在,让我们修正这个缺陷。
Python语句range(x, y)
可以产生x
~y
(包括x
,但不包括y
)的整数。我们也可以采用range(x,y,–1)
的形式,它将产生从x
向下计数到y
(但不包括y
)的整数。因此,list(range(1,7))
的结果是[1,2,3,4,5,6]
,list(range(5,0,–1))
的结果是[5,4,3,2,1]
。我们可以按照任意的步长进行计数,比如list (range(1,10,2))
采用差值为2
的步长,结果是[1,3,5,7,9]
。