在列表中查找最大值(和索引)的 Pythonic 方法

Pythonic way to find highest values (and indexes) in list

我有一个整数列表,我想在列表中找到最高值(最大值和最接近值)及其对应的索引值。

我有一个方法,但我觉得太绕了!

lst = [10,6,17,99,3,1,-3,47, 99]
max_value = (max(lst))
largest = 0.0
largest_index = 0
second_largest = 0.0
second_largest_index = 0
third_largest = 0
third_largest_index = 0
for (index,value) in enumerate (lst):
        if value == largest_value:
            if largest == 0.0:
                largest = value
                largest_index = index
            elif largest != 0.0 and value > second_largest:
                second_largest = value
                second_largest_index= index
            elif second_largest != 0.0 and value > third_largest:
                third_largest = value
                third_largest_index = index
            elif third_largest != 0.0 and value > third_largest:
                fourth_largest = value
                fourth_largest_index = index

        elif value > second_largest and value < largest_value:
            second_largest = value
            second_largest_index = index
        elif value > third_largest and value < second_largest:
            third_largest = value
            third_largest_index = index
        elif value > fourth_largest and value < third_largest:
            fourth_largest = value
            fourth_largest_index = index
    indexlist = [largest_index, second_largest_index, third_largest_index, fourth_largest_index]
return indexlist

因为列表可能有重复的值(我想保留),所以四个最大的值最终可能是 "a,a,b,c"。所以我试图同时找到最大值和 second/third/etc 最大值。

因为我正在尝试查找索引值,所以我认为对列表进行排序不会有帮助。有没有办法保留原始列表的索引,以便在我从最高到最低对列表进行排序时也修改它?

为清楚起见进行编辑:可能是我有 [99,95, 50, 90,99](多次出现最大值)或 [99, 70, 70, 90,50]。我想做的是找到最高值——可能但不一定多次出现最大值。

IIUC,你想要这样的东西(非常快 - 不需要排序所以在 O(n) 中运行):

>>> lst = [10, 6, 17, 99, 3, 1, -3, 47, 99] # avoid using "list"
>>> max_value = max(lst) # get max value
>>> max_index = lst.index(max_value) # get its index
>>> max_index, max_value
(3, 99)

如果您需要 all 个最高值的索引:

>>> max_value = max(lst)
>>> [i for i, j in enumerate(lst) if j == max_value]
[3, 8]

并结合他们的价值观:

>>> [(i,j) for (i, j) in enumerate(lst) if j == max_value]
[(3, 99), (8, 99)]

创建一个可迭代的值和索引元组(按该顺序)并对其进行排序。元组排序在第一个元素上完成(如果相等,则在第二个元素上,依此类推):

sorted(((value, index) for index, value in enumerate(list_of_values)), reverse=True)

在您的示例中,输出为:

[(99, 8), (99, 3), (47, 7), (17, 2), (10, 0), (6, 1), (3, 4), (1, 5), (-3, 6)]

A:创建存储原始索引和值的新元组列表

B:将列表从高到低排序

C:取4个最高元素

D:使用它们

list_is_a_bad_name = [10,6,17,99,3,1,-3,47, 99]
the_list_with_indexes = [(idx, i) for idx, i in  enumerate(list_is_a_bad_name)]
sorted_list = sorted(the_list_with_indexes, reverse=True, key=lambda i:i[1])

for i in sorted_list[:4]:
    print("{} - {}".format(i[0], i[1]))

如果你只想找到最大的数:

l = [10,6,17,99,3,1,-3,47, 99]
max_id, max_no = max(enumerate(l), key=lambda x: x[1])

对于最大的 k 个数字,您可以使用 heapq 模块:

from heapq import nlargest
l = [10,6,17,99,3,1,-3,47, 99]
k = 3
nmax = nlargest(k, enumerate(a), key=lambda x:x[1])  # returns list of (index, value)

一个(可能矫枉过正)但非常干净的解决方案是:

lst = [10, 6, 17, 99, 3, 1, -3, 47, 99]
meta_lst = list(enumerate(lst))

然后按值排序(也就是第二个元素)

from operators import itemgetter
sorted_meta_lst = sorted(meta_lst, key=itemgetter(1))

你将有越来越多的成对(列表中的索引,值)。

mylist = [10,6,17,99,3,1,-3,47, 99]
maximum = max(mylist)
print maximum, [i for i, j in enumerate(mylist) if j == maximum]

99 [3, 8]

适用于 python 2.7

import heapq
print heapq.nlargest(len(mylist), enumerate(mylist),  key=lambda x: x[1])
[(3, 99), (8, 99), (7, 47), (2, 17), (0, 10), (1, 6), (4, 3), (5, 1), (6, -3)]

也适用于 python 2.7

您可以这样做:创建一个值-索引对元组,使用这些值对元组进行排序,然后选择第 n 个第一个(或最后一个)值:

mylist = [10,6,17,99,3,1,-3,47, 99]
tup = zip(mylist, range(len(mylist)))
sorted_list = sorted(tup, key=lambda v: v[0], reverse=True)
print sorted_list[:4] # [(99, 3), (99, 8), (47, 7), (17, 2)]

在执行 lsit 时收集索引:

lst = [10,6,17,99,3,1,-3,47, 99]
best = lst[0]
idxlst = [0]
for k,v in enumerate(lst[1:]):
    if (v > best):
        best = v
        idxlst = [k+1]
    elif (v == best):
        idxlst.append(k+1)