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

for i in range(9):
    new_board = current_board.new_board_with_move([i / 3, i % 3], player)

    if new_board:
        temp = min_max(new_board, depth + 1, not is_min_level)  
        values.append(temp)

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

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


当前回答

只要你知道如何使用lambda和"key"参数,一个简单的解决方案是:

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

其他回答

假设您有一个列表values =[3,6,1,5],并且需要最小元素的索引,即在本例中index_min = 2。

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

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

因为它不需要导入操作符,也不需要使用枚举,而且它总是比使用itemgetter()的解决方案更快(下面的基准测试)。

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

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

这将比第一个解决方案更快,即使你将它应用于一个纯Python列表,如果:

它比一些元素大(在我的机器上大约2**4个元素) 您可以将内存从纯列表复制到numpy数组

正如这一基准所指出的:

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

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

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

要获得比第一次遇到的更多信息,请使用sort方法。

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)]

我认为最好的方法是将列表转换为numpy数组并使用这个函数:

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

如果你想在一个数字列表中找到max的下标(这似乎是你的情况),那么我建议你使用numpy:

import numpy as np
ind = np.argmax(mylist)
seq=[1.1412, 4.3453, 5.8709, 0.1314]
seq.index(min(seq))

会给出最小值的第一个指数。