查找列表中的两个最小值

Finding two smallest values in a list

我正在尝试 return 将数字列表的两个最小值作为元组。 但是,下一个代码保留 returning 列表的前两个值。

def test(): 
  list = [4, 5, 1, 9, -2, 0, 3, -5] 
  min1 = list[0]
  min2 = list[1]

  length = len(list)
  
  for i in range(1, length):
    if list[i] < list[0]:
        if list[0] < list[1]:
            list[i] = list[1]
        else:
            list[i] = list[1] 
    else:
        if list[i] < list[1]:
            list[i] = list[1]
    print(min1, min2)

    return (min1, min2) 

test()

控制台输出:

4,5

有没有办法通过迭代来做到这一点?

变量 min1min2 不更新,它们不是对列表第一个和第二个元素的引用,它们是对索引 0 和 1 处的值的引用分配发生的时间。您稍后更改 list[0]list[1] 无关紧要。

在Python中,列表索引和变量都只是对实际对象的引用。想想像气球这样的 Python 对象,变量和索引只是与气球上的字符串相关联的标签。您可以将多个标签附加到气球,但如果您将标签移动到不同的气球,则绑定到旧气球的 other 标签不会跟随。

这里,min1min2 绑定到已经绑定了 01 索引标签的气球。稍后,当您分配给 list[i] 时,您将特定的索引标签重新绑定到另一个气球,但 min1min2 标签没有改变。

附带说明一下,您的这部分代码有一个相当明显的错误:

if list[0] < list[1]:
    list[i] = list[1]
else:
    list[i] = list[1] 

两个分支做完全相同的事情,将 list[1] 分配给 list[i]

即使您希望在循环内更改 list[0]list[1] 会更改 min1 和 [=13= 的值,但您还是在做完全错误的赋值],您正在更改 list[i],列表中的 other 值,该值应该更小。

所以对于 i = 2list[i]list[2] 并且 list[2] < list[0] 是真的(1 < 4),然后你测试是否 list[0] < list[1](也是真的, 4 < 5), 所以你做 list[i] = list[1], 设置 list[2] = 5, 将 list[0] 设置为 4, list[1] 设置为 5, 并且实际上丢弃了 list[2] 之前存在的 1 值。

与其与 list[0]list[1] 进行比较,不如让循环更新 min1min2:

# min1 is always smaller than min2
min1, min2 = list[:2]
if min2 < min1:
    min1, min2 = min2, min1

for i in range(1, length):
    if list[i] < min1:
        min1 = list[i]
    elif list[i] < min2:  # but equal to or greater than min1!
        min2 = list[i]

我还确保 min1 < min2 在开始时,这使得循环更简单,因为如果 list[i] < min1 不正确,那么它可以 或许 小于 min2 但您不需要再次针对 min1 进行测试。

注意这里我们给min1min2赋值list[i],你要更新这两个变量的值你刚刚测试过,前提是 list[i] 确实比你之前的要小。