使用列表中的max()/ min()获取返回的max或min项的索引

时间:2010-03-18 23:20:36

标签: python list max min

我在minimax算法的列表上使用Python的maxmin函数,我需要max()min()返回的值的索引。换句话说,我需要知道哪个移动产生了最大值(在第一个玩家的回合)或最小值(第二个玩家)值。

for i in range(9):
    newBoard = currentBoard.newBoardWithMove([i / 3, i % 3], player)

    if newBoard:
        temp = minMax(newBoard, depth + 1, not isMinLevel)  
        values.append(temp)

if isMinLevel:
    return min(values)
else:
    return max(values)

我需要能够返回最小值或最大值的实际索引,而不仅仅是值。

24 个答案:

答案 0 :(得分:381)

假设您有一个列表values = [3,6,1,5],并且需要最小元素的索引,在这种情况下需要index_min = 2

避免使用其他答案中显示itemgetter()的解决方案,而是使用

index_min = min(xrange(len(values)), key=values.__getitem__)

因为它不需要import operator也不需要使用enumerate,并且它总是比使用itemgetter()的解决方案更快(下面的基准)。

如果您正在处理numpy数组或者可以将numpy作为依赖项,请考虑使用

import numpy as np
index_min = np.argmin(values)

即使您将其应用于纯Python列表,这将比第一个解决方案更快:

  • 它大于几个元素(我机器上大约2 ** 4个元素)
  • 您可以将内存副本从纯列表提供给numpy数组

正如此基准指出: enter image description here

我已经在我的机器上使用python 2.7运行基准测试,用于上面的两个解决方案(蓝色:纯python,第一个解决方案)(红色,numpy解决方案)和基于itemgetter()的标准解决方案(黑色,参考)解)。 与python 3.5相同的基准测试表明,这些方法与上面提到的python 2.7案例完全相同

答案 1 :(得分:310)

如果列举列表中的项目,则可以同时找到最小/最大索引和值,但对列表的原始值执行最小值/最大值。像这样:

import operator
min_index, min_value = min(enumerate(values), key=operator.itemgetter(1))
max_index, max_value = max(enumerate(values), key=operator.itemgetter(1))

这样,列表只会在最小(或最大)时间内遍历一次。

答案 2 :(得分:292)

if isMinLevel:
    return values.index(min(values))
else:
    return values.index(max(values))

答案 3 :(得分:103)

如果你想在数字列表中找到最大索引(这似乎是你的情况),那么我建议你使用numpy:

import numpy as np
ind = np.argmax(mylist)

答案 4 :(得分:34)

可能更简单的解决方案是将值数组转换为值数组,索引对,并取最大值/最小值。这将给出具有最大/最小的最大/最小索引(即,通过首先比较第一元素,然后比较第二元素,如果第一元素相同,则比较对)。请注意,没有必要实际创建数组,因为min / max允许生成器作为输入。

values = [3,4,5]
(m,i) = max((v,i) for i,v in enumerate(values))
print (m,i) #(5, 2)

答案 5 :(得分:26)

list=[1.1412, 4.3453, 5.8709, 0.1314]
list.index(min(list))

会给你第一个最低指数。

答案 6 :(得分:11)

我也对此感兴趣,并使用perfplot(我的宠物项目)比较了一些建议的解决方案。

原来numpy's argmin

numpy.argmin(x)
对于足够大的列表,

是最快的方法,即使是从输入listnumpy.array的隐式转换。

enter image description here

生成情节的代码:

import numpy
import operator
import perfplot


def min_enumerate(a):
    return min(enumerate(a), key=lambda x: x[1])[0]


def min_enumerate_itemgetter(a):
    min_index, min_value = min(enumerate(a), key=operator.itemgetter(1))
    return min_index


def getitem(a):
    return min(range(len(a)), key=a.__getitem__)


def np_argmin(a):
    return numpy.argmin(a)


perfplot.show(
    setup=lambda n: numpy.random.rand(n).tolist(),
    kernels=[
        min_enumerate,
        min_enumerate_itemgetter,
        getitem,
        np_argmin,
        ],
    n_range=[2**k for k in range(15)],
    logx=True,
    logy=True,
    )

答案 7 :(得分:8)

使用numpy数组和argmax()函数

 a=np.array([1,2,3])
 b=np.argmax(a)
 print(b) #2

答案 8 :(得分:7)

获得最大值后,请尝试以下操作:

max_val = max(list)
index_max = list.index(max_val)

比许多选项简单得多。

答案 9 :(得分:6)

我认为最好的方法是将列表转换为numpy array并使用此功能:

a = np.array(list)
idx = np.argmax(a)

答案 10 :(得分:6)

使用numpy模块的功能numpy.where

import numpy as n
x = n.array((3,3,4,7,4,56,65,1))

对于最小值索引:

idx = n.where(x==x.min())[0]

对于最大值的索引:

idx = n.where(x==x.max())[0]

事实上,这个功能更强大。您可以构建各种布尔运算 对于3到60之间的值索引:

idx = n.where((x>3)&(x<60))[0]
idx
array([2, 3, 4, 5])
x[idx]
array([ 4,  7,  4, 56])

答案 11 :(得分:4)

这可以使用内置的enumerate()max()函数以及key函数的可选max()参数和一个简单的lambda表达式来实现:

theList = [1, 5, 10]
maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1])
# => (2, 10)

max()的文档中,它表示key参数需要list.sort()函数中的函数。另请参阅Sorting How To

min()的工作方式相同。顺便说一下,它返回第一个最大/最小值。

答案 12 :(得分:4)

假设您有一个列表,例如:

a = [9,8,7]

以下两种方法是获得具有最小元素及其索引的元组的非常紧凑的方法。两者都需要类似的时间来处理。我更喜欢拉链方法,但那是我的口味。

zip方法

element, index = min(list(zip(a, range(len(a)))))

min(list(zip(a, range(len(a)))))
(7, 2)

timeit min(list(zip(a, range(len(a)))))
1.36 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

枚举方法

index, element = min(list(enumerate(a)), key=lambda x:x[1])

min(list(enumerate(a)), key=lambda x:x[1])
(2, 7)

timeit min(list(enumerate(a)), key=lambda x:x[1])
1.45 µs ± 78.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

答案 13 :(得分:4)

只要你知道如何使用lambda和&#34; key&#34;论证,一个简单的解决方案是:

max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] )

答案 14 :(得分:4)

我认为上面的答案解决了你的问题,但我想我会分享一种方法,它会给你最小值,所有指数都会出现在最低点。

minval = min(mylist)
ind = [i for i, v in enumerate(mylist) if v == minval]

这会两次通过列表,但仍然非常快。然而,它比找到最小值的第一次遭遇的指数稍慢。因此,如果您只需要其中一个最小值,请使用Matt Anderson的解决方案,如果您需要全部,请使用此方法。

答案 15 :(得分:3)

为什么要先添加索引然后反转呢? Enumerate()函数只是zip()函数用法的一个特例。让我们以适当的方式使用它:

my_indexed_list = zip(my_list, range(len(my_list)))

min_value, min_index = min(my_indexed_list)
max_value, max_index = max(my_indexed_list)

答案 16 :(得分:2)

如果您不想导入其他模块,可以在列表中查找值最小的索引的简单方法:

min_value = min(values)
indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value]

然后选择第一个:

choosen = indexes_with_min_value[0]

答案 17 :(得分:2)

只是对已经说过的一点点补充。 values.index(min(values))似乎返回min的最小索引。以下是最大的索引:

    values.reverse()
    (values.index(min(values)) + len(values) - 1) % len(values)
    values.reverse()

如果反转的副作用无关紧要,可以省略最后一行。

迭代所有出现次数

    indices = []
    i = -1
    for _ in range(values.count(min(values))):
      i = values[i + 1:].index(min(values)) + i + 1
      indices.append(i)

为了简洁起见。将min(values), values.count(min)缓存在循环之外可能是个更好的主意。

答案 18 :(得分:2)

Pandas现在有了一个更为温和的解决方案,请尝试一下:

df[column].idxmax()

答案 19 :(得分:1)

简单:

stuff = [2, 4, 8, 15, 11]

index = stuff.index(max(stuff))

答案 20 :(得分:1)

没有足够高的代表对现有答案发表评论。

https://stackoverflow.com/a/11825864/3920439回答

这适用于整数,但不适用于浮点数组(至少在python 3.6中) 它会引发TypeError: list indices must be integers or slices, not float

答案 21 :(得分:0)

https://docs.python.org/3/library/functions.html#max

如果多个项目是最大的,则该函数返回遇到的第一个项目。这与其他排序稳定性保留工具(如sorted(iterable, key=keyfunc, reverse=True)[0]

)一致

要获得的不仅仅是第一次使用排序方法。

import operator

x = [2, 5, 7, 4, 8, 2, 6, 1, 7, 1, 8, 3, 4, 9, 3, 6, 5, 0, 9, 0]

min = False
max = True

min_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = min )

max_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = max )


min_val_index[0]
>(0, 17)

max_val_index[0]
>(9, 13)

import ittertools

max_val = max_val_index[0][0]

maxes = [n for n in itertools.takewhile(lambda x: x[0] == max_val, max_val_index)]

答案 22 :(得分:0)

那呢:

a=[1,55,2,36,35,34,98,0]
max_index=dict(zip(a,range(len(a))))[max(a)]

它从a中的项作为键,并以它们的索引作为值来创建字典,因此dict(zip(a,range(len(a))))[max(a)]返回与键max(a)相对应的值,该键是最大索引在一个。我是python的初学者,所以我不知道该解决方案的计算复杂性。

答案 23 :(得分:-1)

假设您有以下列表my_list = [1,2,3,4,5,6,7,8,9,10],并且我们知道如果执行max(my_list),它将返回10,而min(my_list)将返回1。现在我们要获取最大或最小元素的索引,我们可以执行以下操作。

my_list = [1,2,3,4,5,6,7,8,9,10]

max_value = max(my_list) # returns 10
max_value_index = my_list.index(max_value) # retuns 9

#to get an index of minimum value

min_value = min(my_list) # returns 1
min_value_index = my_list.index(min_value) # retuns 0