在列表中使用max()/ min()获取返回的最大值或最小值项目的索引
我在列表中使用Python的max
和min
函数,并且我需要由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)
我需要能够返回最小值或最大值的实际索引,而不仅仅是值。
如果isMinLevel: 返回values.index(min(values)) 其他: 返回values.index(最大(值))
如果枚举列表中的项目,但是对列表的原始值执行最小/最大值,则可以同时查找最小/最大索引和值。 像这样:
import operator min_index, min_value = min(enumerate(values), key=operator.itemgetter(1)) max_index, max_value = max(enumerate(values), key=operator.itemgetter(1))
这样,列表只会在min(或max)中遍历一次。
假设你有一个列表values = [3,6,1,5]
,并且需要最小元素的索引,即在这种情况下index_min = 2
。
避免与其他答案中提供的itemgetter()
解决scheme,并改为使用
index_min = min(xrange(len(values)), key=values.__getitem__)
因为它不需要import operator
也不需要使用enumerate
,并且比使用itemgetter()
的解决scheme总是更快(基准低于itemgetter()
。
如果你正在处理numpy数组或者可以将numpy
作为依赖,那么也可以考虑使用
import numpy as np index_min = np.argmin(values)
即使将其应用于纯Python列表,这将比第一个解决scheme更快:
- 它大于一些元素(我的机器上大约有2 ** 4个元素)
- 你可以承担从纯粹的列表内存拷贝到一个
numpy
数组
正如这个基准指出的那样:
我已经在我的机器上运行了Python 2.7的基准testing(蓝色:纯Python,第一个解决scheme)(红色,numpy解决scheme)和基于itemgetter()
(黑色,参考解决scheme)的标准解决scheme。 与python 3.5相同的基准testing表明,这些方法与上面介绍的python 2.7的情况完全相同
如果你想find一个数字列表中的最大指标(这似乎是你的情况),那么我build议你使用numpy:
import numpy as np ind = np.argmax(mylist)
可能更简单的解决scheme是将值的数组转换为一个值的数组,索引对,并取其最大值/最小值。 这将给出具有最大/最小值的最大/最小索引(即,通过首先比较第一个元素,然后比较第一个元素,如果第一个元素相同,则比较对)。 请注意,没有必要实际创build数组,因为min / max允许生成器作为input。
values = [3,4,5] (m,i) = max((v,i) for i,v in enumerate(values)) print (m,i) #(5, 2)
list=[1.1412, 4.3453, 5.8709, 0.1314] list.index(min(list))
会给你最低的第一个索引。
使用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]
其实这个function要强大得多。 您可以构成各种布尔操作对于3到60之间的值的索引:
idx = n.where((x>3)&(x<60))[0] idx array([2, 3, 4, 5]) x[idx] array([ 4, 7, 4, 56])
使用内build的enumerate()
和max()
函数以及max()
函数和一个简单的lambdaexpression式的可选key
参数,
theList = [1, 5, 10] maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1]) # => (2, 10)
在max()
的文档中说, key
参数需要像list.sort()
函数中的函数。 另请参阅sorting方法 。
它对min()
作用是一样的。 顺便说一句,它返回第一个最大/最小值。
为什么要麻烦先添加索引,然后把它们倒过来呢? 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)
只要你知道如何使用lambda和“key”参数,一个简单的解决scheme是:
max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] )
只是对已经说过的一点点补充。 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)
为了简洁起见。 在循环之外cachingmin(values), values.count(min)
可能是个好主意。
我想上面的答案解决了你的问题,但我想我会分享一个方法,让你的最低限度,所有的指数最低出现在。
minval = min(mylist) ind = [i for i, v in enumerate(mylist) if v == minval]
这两次通过列表,但仍然相当快。 然而,它比find最小值的第一次遇到的索引稍慢。 所以,如果你只需要一个最小值,使用马特安德森的解决scheme,如果你需要它们,使用这个。
如果您不想导入其他模块,可以使用一种简单的方法在列表中查找具有最小值的索引:
min_value = min(values) indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value]
然后select例如第一个:
choosen = indexes_with_min_value[0]
我也对此感兴趣,并比较了一些使用perfplot (我的一个宠物项目)的build议解决scheme。
原来, numpy的argmin是足够大的列表的最快方法,即使从inputlist
隐式转换为numpy.array
。
生成图的代码:
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, )
https://docs.python.org/3/library/functions.html#max
如果多个项目是最大的,该函数返回遇到的第一个。 这与其他sorting稳定性保持工具如sorted(iterable, key=keyfunc, reverse=True)[0]
为了不仅仅是第一次使用sorting方法。
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)]
就那么简单 :
stuff = [2, 4, 8, 15, 11] index = stuff.index(max(stuff))