我正在使用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)
我需要能够返回最小值或最大值的实际索引,而不仅仅是值。
使用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])
假设您有一个列表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情况完全相同
可能更简单的解决方案是将值数组转换为值、索引对数组,并取其中的最大/最小值。这将给出具有max/min的最大/最小索引(即对的比较首先比较第一个元素,然后比较第二个元素,如果第一个元素相同)。注意,没有必要实际创建数组,因为min/max允许生成器作为输入。
values = [3,4,5]
(m,i) = max((v,i) for i,v in enumerate(values))
print (m,i) #(5, 2)
我对此也很感兴趣,并使用perfplot(我的一个爱好项目)比较了一些建议的解决方案。
事实证明
min(range(len(a)), key=a.__getitem__)
是用于小型和大型列表的最快方法。
在以前的版本中,np。阿格明过去常吃蛋糕。)
生成图的代码:
import numpy as np
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 np.argmin(a)
b = perfplot.bench(
setup=lambda n: np.random.rand(n).tolist(),
kernels=[
min_enumerate,
min_enumerate_itemgetter,
getitem,
np_argmin,
],
n_range=[2**k for k in range(15)],
)
b.show()