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

时间:2022-09-27 10:31:52

I'm using Python's max and min functions on lists for a minimax algorithm, and I need the index of the value returned by max() or min(). In other words, I need to know which move produced the max (at a first player's turn) or min (second player) value.

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

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)

I need to be able to return the actual index of the min or max value, not just the value.

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

20 个解决方案

#1


190  

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

#2


264  

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:

如果枚举列表中的项,可以同时找到min/max索引和值,但是在列表的原始值上执行min/max。像这样:

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

This way the list will only be traversed once for min (or max).

这样,列表将只遍历一次(或最大)。

#3


257  

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.

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

Avoid the solution with itemgetter() presented in the other answers, and use instead

避免用itemgetter()给出其他答案中的解决方案,并使用它。

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

because it doesn't require to import operator nor to use enumerate, and it is always faster(benchmark below) than a solution using itemgetter().

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

If you are dealing with numpy arrays or can afford numpy as a dependency, consider also using

如果您处理的是numpy数组,或者可以负担得起numpy作为依赖项,请考虑使用。

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

This will be faster than the first solution even if you apply it to a pure Python list if:

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

  • it is larger than a few elements (about 2**4 elements on my machine)
  • 它比几个元素大(我的机器上大约有2**4个元素)
  • you can afford the memory copy from a pure list to a numpy array
  • 您可以从纯列表到numpy数组提供内存副本。

as this benchmark points out: 在列表中使用max()/min()获取返回的max或min项的索引。

正如这个基准所指出的:

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

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

#4


79  

If you want to find the index of max within a list of numbers (which seems your case), then I suggest you use numpy:

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

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

#5


31  

Possibly a simpler solution would be to turn the array of values into an array of value,index-pairs, and take the max/min of that. This would give the largest/smallest index that has the max/min (i.e. pairs are compared by first comparing the first element, and then comparing the second element if the first ones are the same). Note that it's not necessary to actually create the array, because min/max allow generators as input.

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

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

#6


18  

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

Will give you first index of minimum.

会给你一个最小的指数。

#7


7  

Use numpy module's function numpy.where

使用numpy模块的函数numpy.where。

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

For index of minimum value:

最小值指数:

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

For index of maximum value:

最大值的索引:

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

In fact, this function is much more powerful. You can pose all kinds of boolean operations For index of value between 3 and 60:

事实上,这个函数更强大。您可以对3到60之间的值进行各种布尔操作。

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

#8


5  

I was also interested in this and compared some of the suggested solutions using perfplot (a pet project of mine).

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

Turns out that numpy's argmin,

结果是numpy的argmin,

numpy.argmin(x)

is the fastest method for large enough lists, even with the implicit conversion from the input list to a numpy.array.

是最大的列表的最快方法,即使是从输入列表到numpy.array的隐式转换。

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


Code for generating the plot:

生成情节的代码:

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

#9


4  

This is simply possible using the built-in enumerate() and max() function and the optional key argument of the max() function and a simple lambda expression:

使用内置的enumerate()和max()函数以及max()函数和一个简单lambda表达式的可选关键参数,这是可能的。

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

In the docs for max() it says that the key argument expects a function like in the list.sort() function. Also see the Sorting How To.

在max()的文档中,它说关键参数期望在list.sort()函数中有一个函数。还可以看到排序的方法。

It works the same for min(). Btw it returns the first max/min value.

对min()也适用。它返回第一个max/min值。

#10


4  

As long as you know how to use lambda and the "key" argument, a simple solution is:

只要您知道如何使用lambda和“关键”参数,一个简单的解决方案是:

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

#11


3  

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:

为什么要先添加索引然后反转它们呢?枚举()函数只是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)

#12


2  

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:

只是对已经说过的内容稍加补充。value .index(min(值))似乎返回最小的最小索引。

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

The last line can be left out if the side effect of reversing in place does not matter.

如果反转的副作用不重要的话,最后一行可以省略。

To iterate through all occurrences

循环遍历所有的事件。

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

For the sake of brevity. It is probably a better idea to cache min(values), values.count(min) outside the loop.

为了简洁。在循环之外缓存最小值(值)可能是一个更好的主意。

#13


2  

Use a numpy array and the argmax() function

使用numpy数组和argmax()函数。

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

#14


1  

I think the answer above solves your problem but I thought I'd share a method that gives you the minimum and all the indices the minimum appears in.

我认为上面的答案可以解决你的问题,但我认为我应该分享一种方法,给你最小值和最小值的所有指标。

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

This passes the list twice but is still quite fast. It is however slightly slower than finding the index of the first encounter of the minimum. So if you need just one of the minima, use Matt Anderson's solution, if you need them all, use this.

这个列表两次通过,但仍然非常快。不过,它比第一次遇到最小值的索引要慢一些。如果你只需要一个最小值,用马特·安德森的解决方案,如果你需要的话,就用这个。

#15


1  

A simple way for finding the indexes with minimal value in a list if you don't want to import additional modules:

如果您不想导入其他模块,那么在列表中找到具有最小值的索引的简单方法:

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

Then choose for example the first one:

然后选择第一个例子:

choosen = indexes_with_min_value[0]

#16


1  

Simple as that :

简单:

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

index = stuff.index(max(stuff))

#17


1  

Dont have high enough rep to comment on existing answer.

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

But for https://*.com/a/11825864/3920439 answer

但是https://*.com/a/11825864/3920439回答

This works for integers, but does not work for array of floats (at least in python 3.6) It will raise TypeError: list indices must be integers or slices, not float

这适用于整数,但不适用于浮点数组(至少在python 3.6中),它将提高类型错误:列表索引必须是整数或片,而不是浮点数。

#18


1  

Say you have a list such as:

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

a = [9,8,7]

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方法,但那是我的爱好。

zip method

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)

enumerate method

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)

#19


0  

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

https://docs.python.org/3/library/functions.html马克斯

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]

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

To get more than just the first use the sort method.

要得到的不仅仅是第一个使用排序方法。

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

#20


0  

After you get the maximum values

在得到最大值之后。

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

' max_val = max(列表)index_max = list.index(max_val)'

Much simpler than a lot of options..

比很多选择都简单。

#1


190  

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

#2


264  

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:

如果枚举列表中的项,可以同时找到min/max索引和值,但是在列表的原始值上执行min/max。像这样:

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

This way the list will only be traversed once for min (or max).

这样,列表将只遍历一次(或最大)。

#3


257  

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.

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

Avoid the solution with itemgetter() presented in the other answers, and use instead

避免用itemgetter()给出其他答案中的解决方案,并使用它。

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

because it doesn't require to import operator nor to use enumerate, and it is always faster(benchmark below) than a solution using itemgetter().

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

If you are dealing with numpy arrays or can afford numpy as a dependency, consider also using

如果您处理的是numpy数组,或者可以负担得起numpy作为依赖项,请考虑使用。

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

This will be faster than the first solution even if you apply it to a pure Python list if:

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

  • it is larger than a few elements (about 2**4 elements on my machine)
  • 它比几个元素大(我的机器上大约有2**4个元素)
  • you can afford the memory copy from a pure list to a numpy array
  • 您可以从纯列表到numpy数组提供内存副本。

as this benchmark points out: 在列表中使用max()/min()获取返回的max或min项的索引。

正如这个基准所指出的:

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

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

#4


79  

If you want to find the index of max within a list of numbers (which seems your case), then I suggest you use numpy:

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

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

#5


31  

Possibly a simpler solution would be to turn the array of values into an array of value,index-pairs, and take the max/min of that. This would give the largest/smallest index that has the max/min (i.e. pairs are compared by first comparing the first element, and then comparing the second element if the first ones are the same). Note that it's not necessary to actually create the array, because min/max allow generators as input.

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

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

#6


18  

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

Will give you first index of minimum.

会给你一个最小的指数。

#7


7  

Use numpy module's function numpy.where

使用numpy模块的函数numpy.where。

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

For index of minimum value:

最小值指数:

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

For index of maximum value:

最大值的索引:

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

In fact, this function is much more powerful. You can pose all kinds of boolean operations For index of value between 3 and 60:

事实上,这个函数更强大。您可以对3到60之间的值进行各种布尔操作。

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

#8


5  

I was also interested in this and compared some of the suggested solutions using perfplot (a pet project of mine).

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

Turns out that numpy's argmin,

结果是numpy的argmin,

numpy.argmin(x)

is the fastest method for large enough lists, even with the implicit conversion from the input list to a numpy.array.

是最大的列表的最快方法,即使是从输入列表到numpy.array的隐式转换。

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


Code for generating the plot:

生成情节的代码:

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

#9


4  

This is simply possible using the built-in enumerate() and max() function and the optional key argument of the max() function and a simple lambda expression:

使用内置的enumerate()和max()函数以及max()函数和一个简单lambda表达式的可选关键参数,这是可能的。

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

In the docs for max() it says that the key argument expects a function like in the list.sort() function. Also see the Sorting How To.

在max()的文档中,它说关键参数期望在list.sort()函数中有一个函数。还可以看到排序的方法。

It works the same for min(). Btw it returns the first max/min value.

对min()也适用。它返回第一个max/min值。

#10


4  

As long as you know how to use lambda and the "key" argument, a simple solution is:

只要您知道如何使用lambda和“关键”参数,一个简单的解决方案是:

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

#11


3  

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:

为什么要先添加索引然后反转它们呢?枚举()函数只是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)

#12


2  

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:

只是对已经说过的内容稍加补充。value .index(min(值))似乎返回最小的最小索引。

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

The last line can be left out if the side effect of reversing in place does not matter.

如果反转的副作用不重要的话,最后一行可以省略。

To iterate through all occurrences

循环遍历所有的事件。

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

For the sake of brevity. It is probably a better idea to cache min(values), values.count(min) outside the loop.

为了简洁。在循环之外缓存最小值(值)可能是一个更好的主意。

#13


2  

Use a numpy array and the argmax() function

使用numpy数组和argmax()函数。

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

#14


1  

I think the answer above solves your problem but I thought I'd share a method that gives you the minimum and all the indices the minimum appears in.

我认为上面的答案可以解决你的问题,但我认为我应该分享一种方法,给你最小值和最小值的所有指标。

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

This passes the list twice but is still quite fast. It is however slightly slower than finding the index of the first encounter of the minimum. So if you need just one of the minima, use Matt Anderson's solution, if you need them all, use this.

这个列表两次通过,但仍然非常快。不过,它比第一次遇到最小值的索引要慢一些。如果你只需要一个最小值,用马特·安德森的解决方案,如果你需要的话,就用这个。

#15


1  

A simple way for finding the indexes with minimal value in a list if you don't want to import additional modules:

如果您不想导入其他模块,那么在列表中找到具有最小值的索引的简单方法:

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

Then choose for example the first one:

然后选择第一个例子:

choosen = indexes_with_min_value[0]

#16


1  

Simple as that :

简单:

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

index = stuff.index(max(stuff))

#17


1  

Dont have high enough rep to comment on existing answer.

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

But for https://*.com/a/11825864/3920439 answer

但是https://*.com/a/11825864/3920439回答

This works for integers, but does not work for array of floats (at least in python 3.6) It will raise TypeError: list indices must be integers or slices, not float

这适用于整数,但不适用于浮点数组(至少在python 3.6中),它将提高类型错误:列表索引必须是整数或片,而不是浮点数。

#18


1  

Say you have a list such as:

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

a = [9,8,7]

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方法,但那是我的爱好。

zip method

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)

enumerate method

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)

#19


0  

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

https://docs.python.org/3/library/functions.html马克斯

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]

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

To get more than just the first use the sort method.

要得到的不仅仅是第一个使用排序方法。

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

#20


0  

After you get the maximum values

在得到最大值之后。

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

' max_val = max(列表)index_max = list.index(max_val)'

Much simpler than a lot of options..

比很多选择都简单。