查找列表中的两个最小值
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
有没有办法通过迭代来做到这一点?
变量 min1
和 min2
不更新,它们不是对列表第一个和第二个元素的引用,它们是对索引 0 和 1 处的值的引用分配发生的时间。您稍后更改 list[0]
和 list[1]
无关紧要。
在Python中,列表索引和变量都只是对实际对象的引用。想想像气球这样的 Python 对象,变量和索引只是与气球上的字符串相关联的标签。您可以将多个标签附加到气球,但如果您将标签移动到不同的气球,则绑定到旧气球的 other 标签不会跟随。
这里,min1
和 min2
绑定到已经绑定了 0
和 1
索引标签的气球。稍后,当您分配给 list[i]
时,您将特定的索引标签重新绑定到另一个气球,但 min1
和 min2
标签没有改变。
附带说明一下,您的这部分代码有一个相当明显的错误:
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 = 2
,list[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]
进行比较,不如让循环更新 min1
和 min2
:
# 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
进行测试。
注意这里我们给min1
和min2
赋值list[i]
,你要更新这两个变量的值你刚刚测试过,前提是 list[i]
确实比你之前的要小。
我正在尝试 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
有没有办法通过迭代来做到这一点?
变量 min1
和 min2
不更新,它们不是对列表第一个和第二个元素的引用,它们是对索引 0 和 1 处的值的引用分配发生的时间。您稍后更改 list[0]
和 list[1]
无关紧要。
在Python中,列表索引和变量都只是对实际对象的引用。想想像气球这样的 Python 对象,变量和索引只是与气球上的字符串相关联的标签。您可以将多个标签附加到气球,但如果您将标签移动到不同的气球,则绑定到旧气球的 other 标签不会跟随。
这里,min1
和 min2
绑定到已经绑定了 0
和 1
索引标签的气球。稍后,当您分配给 list[i]
时,您将特定的索引标签重新绑定到另一个气球,但 min1
和 min2
标签没有改变。
附带说明一下,您的这部分代码有一个相当明显的错误:
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 = 2
,list[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]
进行比较,不如让循环更新 min1
和 min2
:
# 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
进行测试。
注意这里我们给min1
和min2
赋值list[i]
,你要更新这两个变量的值你刚刚测试过,前提是 list[i]
确实比你之前的要小。