繁体   English   中英

在 Python 子列表中查找最小值索引 - min() 返回列表中最小值的索引

[英]Find index of minimum value in a Python sublist - min() returns index of minimum value in list

我一直致力于在 Python 中实现常见的排序算法,在进行选择排序时,我遇到了一个问题,即找到子列表的最小值并将其与子列表的第一个值交换,从我的测试来看,这似乎是由于关于我如何在我的程序中使用min()的问题。

这是我的代码:

def selection_sort(li):
    for i in range(0, len(li)):
        a, b = i, li.index(min(li[i:]))
        li[a], li[b] = li[b], li[a]

这适用于其中包含零重复元素的列表:

>>> selection_sort([9,8,7,6,5,4,3,2,1])
[1, 2, 3, 4, 5, 6, 7, 8, 9]

但是,当列表中有重复元素时,它会完全失败。

>>> selection_sort([9,8,8,7,6,6,5,5,5,4,2,1,1])
[8, 8, 7, 6, 6, 5, 5, 5, 4, 2, 9, 1, 1]

我试图通过检查min()在我的代码的第 3 行上所做的事情来解决这个问题,并发现min()按预期返回子列表中最小元素的索引值,但索引是更大的列表而不是子列表,我希望这个实验有助于更清楚地说明:

>>> a = [1,2,1,1,2]
>>> min(a)
1                       # expected
>>> a.index(min(a))
0                       # also expected
>>> a.index(min(a[1:]))
0                       # should be 1?

我不确定是什么导致了这种行为; 可以将li[i:]复制到临时变量b然后执行b.index(min(b)) ,但是对于每个循环将li[i:]复制到b可能需要大量 memory 和选择sort 是一种就地算法,所以我不确定这种方法是否理想。

你没有完全正确地理解这个概念!

li.index(item) 将返回该项目在列表 li 中的第一次出现。 相反,您应该做的是,如果您在子列表中找到最小元素,请同时在子列表中搜索该元素,而不是在整个列表中搜索它。 此外,在切片列表中搜索时,您将获得关于子列表的索引。 尽管您可以通过将起始步骤添加到返回的索引来轻松解决此问题。

解决您的问题的一个小方法是:

def selection_sort(li):
    for i in range(0, len(li)):
        a, b = i, i + li[i:].index(min(li[i:]))
        li[a], li[b] = li[b], li[a]

一种方法是使用列表推导:

idxs = [i for i, val in enumerate(a) if val == min(a)]

或者更好的是,编写自己的代码,渐近更快:

idxs = []
minval = None
for i, val in enumerate(a):
    if minval is None or minval > val:
        idxs = [i]
        minval = val
    elif minval == val:
        idxs.append(i)

当您编写a.index(min(a[1:]))时,您正在搜索a[1:]min的第一次出现,但您正在原始 list中搜索。 这就是为什么你得到0结果。

顺便说一句,您要查找的argmin一般称为 argmin 。 它不包含在纯 python 中,但numpy模块有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM