使用列表上的 max()/min() 获取返回的最大或最小项的索引
我在列表上使用 Python 的 max
和 min
函数来实现极小极大算法,并且我需要 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)
我需要能够返回最小值或最大值的实际索引,而不仅仅是值。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
假设您有一个列表
values = [3,6,1,5]
,并且需要最小元素的索引,即本例中的index_min = 2
。避免使用其他答案中提出的
itemgetter()
解决方案,而是使用它,因为它不需要
import 运算符
也不需要使用enumerate
,并且它总是比使用itemgetter()
的解决方案更快(基准如下)。如果您正在处理 numpy 数组或可以负担 numpy 作为依赖项,请考虑使用
这将比第一个解决方案更快,即使您将其应用于纯 Python 列表,如果
正如该基准测试所指出的:
我已经使用 python 2.7 在我的机器上运行了上述两个解决方案的基准测试(蓝色:纯 python,第一个解决方案)(红色,numpy 解决方案)以及基于
itemgetter( )
(黑色,参考溶液)。与 python 3.5 相同的基准测试表明,这些方法与上面介绍的 python 2.7 情况完全相同
Say that you have a list
values = [3,6,1,5]
, and need the index of the smallest element, i.e.index_min = 2
in this case.Avoid the solution with
itemgetter()
presented in the other answers, and use insteadbecause it doesn't require to
import operator
nor to useenumerate
, and it is always faster(benchmark below) than a solution usingitemgetter()
.If you are dealing with numpy arrays or can afford
numpy
as a dependency, consider also usingThis will be faster than the first solution even if you apply it to a pure Python list if:
numpy
arrayas this benchmark points out:
I have run the benchmark on my machine with python 2.7 for the two solutions above (blue: pure python, first solution) (red, numpy solution) and for the standard solution based on
itemgetter()
(black, reference solution).The same benchmark with python 3.5 showed that the methods compare exactly the same of the python 2.7 case presented above
使用
min()
查找最小值然后使用.index()
:
或最大值:
如果您的列表包含重复的最小值或最大值,这将返回第一个值的索引。
Find the minimum value with
min()
then find that value's index with.index()
:Or the maximum:
If your list contains repeats of the minimum or maximum value this will return the index of the first one.
如果枚举列表中的项目,则可以同时找到最小/最大索引和值,但对列表的原始值执行最小/最大。像这样:
这样列表只会在最小(或最大)内被遍历一次。
You can find the min/max index and value at the same time if you enumerate the items in the list, but perform min/max on the original values of the list. Like so:
This way the list will only be traversed once for min (or max).
使用 NumPy 的
np.argmin()
或np.argmax()
功能:Use NumPy's
np.argmin()
ornp.argmax()
functions:将值数组转换为(值,索引)对数组,并取其中的最大值/最小值。这将返回具有最大/最小值的最大/最小索引(即通过首先比较值,然后如果值相同则比较索引来比较对)。
Turn the array of values into an array of (value,index)-pairs, and take the max/min of that. This returns the largest/smallest index that has the max/min (i.e. pairs are compared by first comparing the value, and then comparing the index if the values are the same).
我在 Python 3.11 上使用 perfplot (我的一个宠物项目)对主要答案进行了基准测试,结果证明
是最快(越低越好):
除非您的数组已经是 numpy 数组。
生成绘图的代码:
I benchmarked the main answers using perfplot (a pet project of mine) on Python 3.11 and it turns out that
is the fastest (lower is better):
unless your array is already a numpy array.
Code for generating the plot:
有两个答案(1,2),包括基准测试,但由于某种原因,它们都没有将
list.index()
包含到其基准测试中,即使在发布的已接受答案中建议了这一点至少在这些答案之前 2 年。list.index()
是此页面上给出的最快选项,包括enumerate
(涉及它的所有版本),__getitem__
和numpy.argmin
。此外,如果列表具有非唯一的最小值,并且您想要获取出现最小值的所有索引,则 while 循环中的
list.index
优于其他选项,例如 numpy 和也枚举
。请注意,您可以通过传递起点(这是list.index
的第二个参数)来限制其搜索从特定索引开始,这对于性能至关重要,因为我们不想搜索从 while 循环的每次迭代开始。以下基准测试(在 Python 3.11.4 和 numpy 1.25.2 上执行)表明,无论列表长度如何,
list.index
的速度几乎是所有其他选项的两倍。左图还显示,对于长列表,getitem
的执行效果与enumerate
(和numpy.argmin
)相同,这表明 gg349 和 Nico 的基准测试已经过时了。右图显示,如果最小值不唯一,并且我们想要找到最小值的所有索引,则如上所述的 while 循环中的
list.index
的性能比竞争选项要好得多涉及enumerate
或 numpy,特别是对于长列表。用于生成上图的代码:
There are two answers (1, 2) that include benchmark but for some reason, neither of them include
list.index()
into their benchmark, even though it was suggested in the accepted answer that was posted at least 2 years before these answers.list.index()
is the fastest option given on this page, includingenumerate
(all versions that involve it),__getitem__
andnumpy.argmin
.Moreover, if the list has a non-unique minimum value and you want to get all indices where the minimum value occurs,
list.index
in a while-loop outperforms other options such as numpy andenumerate
as well. Note that you can limit its search to begin from a particular index by passing the starting point (which is the second argument tolist.index
), which is crucial for performance because we don't want to search from the beginning in every iteration of the while-loop.The following benchmarks (performed on Python 3.11.4 and numpy 1.25.2) show that
list.index
is almost twice as fast as all other options no matter the length of the list. The left graph also shows thatgetitem
performs the same asenumerate
(andnumpy.argmin
) for long lists, which shows that gg349 and Nico's benchmarks are outdated.The right graph shows that if the minimum value is non-unique and we want to find all indices of the minimum value, then
list.index
in a while loop as outlined above performs so much better than competing options involvingenumerate
or numpy, especially for long lists.The code used to produce the figure above:
如果您需要最小值的所有索引(因为最小值可能会在列表中出现多次):
If you need all the indexes of the minimum (because the minimum might appear more than once in the list):
获得最大值后,试试这个:
比很多选项简单得多。
After you get the maximum values, try this:
Much simpler than a lot of options.
这可以使用内置的
enumerate()
和max()
函数以及max()
函数的可选key=
参数和一个简单的lambda< /code> 表达式:
在
max()
它表示key=
参数需要一个类似于list.sort()
函数。另请参阅排序方法。min()
的工作原理相同。顺便说一句,它返回第一个最大/最小值。This is possible using the built-in
enumerate()
andmax()
functions and the optionalkey=
argument of themax()
function and a simplelambda
expression:In the docs for
max()
it says that thekey=
argument expects a function like in thelist.sort()
function. Also see the Sorting HOW TO.It works the same for
min()
. Btw, it returns the first max/min value.Pandas 现在有了一个更温和的解决方案,尝试一下:
df[column].idxmax()
Pandas has now got a much more gentle solution, try it:
df[column].idxmax()
使用 numpy 数组和
argmax()
函数Use a numpy array and the
argmax()
function使用numpy模块的函数numpy.where
对于最小值的索引:
对于最大值的索引:
事实上,这个函数要强大得多。你可以提出各种布尔运算
对于 3 到 60 之间的索引值:
Use numpy module's function numpy.where
For index of minimum value:
For index of maximum value:
In fact, this function is much more powerful. You can pose all kinds of boolean operations
For index of value between 3 and 60:
假设您有一个列表,例如:
以下两种方法是获取具有最小元素及其索引的元组的非常紧凑的方法。两者的处理时间相似。我更喜欢拉链方法,但这就是我的口味。
zip 方法
枚举方法
Say you have a list such as:
The following two methods are pretty compact ways to get a tuple with the minimum element and its index. Both take a similar time to process. I better like the zip method, but that is my taste.
zip method
enumerate method
您可以将 lambda 作为
key=
参数传递给max()
/分钟()
:You can pass a lambda as the
key=
argument tomax()
/min()
:为什么要麻烦先添加索引然后再反转它们呢? Enumerate() 函数只是 zip() 函数用法的一个特例。让我们以适当的方式使用它:
Why bother to add indices first and then reverse them? Enumerate() function is just a special case of zip() function usage. Let's use it in appropiate way:
就这么简单:
Simple as that :
假设您有以下列表
my_list = [1,2,3,4,5,6,7,8,9,10]
并且我们知道如果我们执行max(my_list)
它将返回10
,min(my_list)
将返回1
。现在我们想要获取最大或最小元素的索引,我们可以执行以下操作。Assuming you have a following list
my_list = [1,2,3,4,5,6,7,8,9,10]
and we know that if we domax(my_list)
it will return10
andmin(my_list)
will return1
. Now we want to get the index of the maximum or minimum element we can do the following.https://docs.python.org/3/library/functions.html# max
如果多个项目都最大,则该函数返回遇到的第一个。这与其他排序稳定性保持工具一致,例如
sorted(iterable, key=keyfunc, reverse=True)[0]
要获取不仅仅是第一个遇到的内容,请使用 sort 方法。
https://docs.python.org/3/library/functions.html#max
If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as
sorted(iterable, key=keyfunc, reverse=True)[0]
To get more than just the first encountered, use the sort method.
只是对已经说过的内容进行一点小小的补充。
values.index(min(values))
似乎返回 min 的最小索引。以下获取最大索引:如果原地反转的副作用不重要,则可以省略最后一行。
迭代所有发生的情况
为了简洁起见, 。在循环外部缓存
min(values),values.count(min)
可能是一个更好的主意。Just a minor addition to what has already been said.
values.index(min(values))
seems to return the smallest index of min. The following gets the largest index:The last line can be left out if the side effect of reversing in place does not matter.
To iterate through all occurrences
For the sake of brevity. It is probably a better idea to cache
min(values), values.count(min)
outside the loop.如果您不想导入其他模块,则可以使用一种简单的方法来查找列表中具有最小值的索引:
然后选择第一个模块:
A simple way for finding the indexes with minimal value in a list if you don't want to import additional modules:
Then choose for example the first one:
怎么样:
它从
a
中的项目作为键,将它们的索引作为值创建一个字典,因此dict(zip(a,range(len(a))))[max( a)]
返回与键max(a)
对应的值,它是 a 中最大值的索引。我是 python 的初学者,所以我不知道这个解决方案的计算复杂性。What about this:
It creates a dictionary from the items in
a
as keys and their indexes as values, thusdict(zip(a,range(len(a))))[max(a)]
returns the value that corresponds to the keymax(a)
which is the index of the maximum in a. I'm a beginner in python so I don't know about the computational complexity of this solution.