如何在列表中找到最大值的所有位置?

我有一个清单:

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
35, 41, 49, 37, 19, 40, 41, 31]

最大元素是55(两个元素在位置9和12)

我需要找到在哪个位置(s)的最大值是位于。请帮助。

437739 次浏览
a.index(max(a))

将告诉你列表a中最大值元素的第一个实例的索引。

>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]

这里是最大值和它出现的索引:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> for i, x in enumerate(a):
...     d[x].append(i)
...
>>> k = max(d.keys())
>>> print k, d[k]
55 [9, 12]

后来:为了满足@SilentGhost

>>> from itertools import takewhile
>>> import heapq
>>>
>>> def popper(heap):
...     while heap:
...         yield heapq.heappop(heap)
...
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> h = [(-x, i) for i, x in enumerate(a)]
>>> heapq.heapify(h)
>>>
>>> largest = heapq.heappop(h)
>>> indexes = [largest[1]] + [x[1] for x in takewhile(lambda large: large[0] == largest[0], popper(h))]
>>> print -largest[0], indexes
55 [9, 12]
所选的答案(和大多数其他答案)需要至少两次遍历列表 这里有一个一次性的解决方案,对于较长的列表可能是一个更好的选择。< / p >

为了解决@John Machin指出的两个缺陷。对于(2),我尝试基于每个条件发生的猜测概率和前人允许的推论来优化测试。为max_valmax_indices找出合适的初始化值有点棘手,这适用于所有可能的情况,特别是如果max恰好是列表中的第一个值-但我相信现在是这样。

def maxelements(seq):
''' Return list of position(s) of largest element '''
max_indices = []
if seq:
max_val = seq[0]
for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val):
if val == max_val:
max_indices.append(i)
else:
max_val = val
max_indices = [i]


return max_indices

我无法重现@martineau引用的@SilentGhost-beating的表演。以下是我的比较结果:

=== maxelements.py ===

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
35, 41, 49, 37, 19, 40, 41, 31]
b = range(10000)
c = range(10000 - 1, -1, -1)
d = b + c


def maxelements_s(seq): # @SilentGhost
''' Return list of position(s) of largest element '''
m = max(seq)
return [i for i, j in enumerate(seq) if j == m]


def maxelements_m(seq): # @martineau
''' Return list of position(s) of largest element '''
max_indices = []
if len(seq):
max_val = seq[0]
for i, val in ((i, val) for i, val in enumerate(seq) if val >= max_val):
if val == max_val:
max_indices.append(i)
else:
max_val = val
max_indices = [i]
return max_indices


def maxelements_j(seq): # @John Machin
''' Return list of position(s) of largest element '''
if not seq: return []
max_val = seq[0] if seq[0] >= seq[-1] else seq[-1]
max_indices = []
for i, val in enumerate(seq):
if val < max_val: continue
if val == max_val:
max_indices.append(i)
else:
max_val = val
max_indices = [i]
return max_indices

在Windows XP SP3上运行Python 2.7的旧笔记本电脑的结果:

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_s(me.a)"
100000 loops, best of 3: 6.88 usec per loop


>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_m(me.a)"
100000 loops, best of 3: 11.1 usec per loop


>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_j(me.a)"
100000 loops, best of 3: 8.51 usec per loop


>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_s(a100)"
1000 loops, best of 3: 535 usec per loop


>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_m(a100)"
1000 loops, best of 3: 558 usec per loop


>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_j(a100)"
1000 loops, best of 3: 489 usec per loop
import operator


def max_positions(iterable, key=None, reverse=False):
if key is None:
def key(x):
return x
if reverse:
better = operator.lt
else:
better = operator.gt


it = enumerate(iterable)
for pos, item in it:
break
else:
raise ValueError("max_positions: empty iterable")
# note this is the same exception type raised by max([])
cur_max = key(item)
cur_pos = [pos]


for pos, item in it:
k = key(item)
if better(k, cur_max):
cur_max = k
cur_pos = [pos]
elif k == cur_max:
cur_pos.append(pos)


return cur_max, cur_pos


def min_positions(iterable, key=None, reverse=False):
return max_positions(iterable, key, not reverse)

>>> L = range(10) * 2
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> max_positions(L)
(9, [9, 19])
>>> min_positions(L)
(0, [0, 10])
>>> max_positions(L, key=lambda x: x // 2, reverse=True)
(0, [0, 1, 10, 11])

类似的想法与列表理解,但没有枚举

m = max(a)
[i for i in range(len(a)) if a[i] == m]

你也可以使用numpy包:

import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))

这将返回包含max值的所有下标的numpy数组

如果你想把它变成一个列表:

maximum_indices_list = maximum_indices.tolist()

我想出了以下方法,它的工作原理正如你可以看到的那样,在列表上使用maxmin和其他函数:

因此,请考虑下一个示例列表,找出最大在列表a中的位置:

>>> a = [3,2,1, 4,5]

使用发电机 enumerate并进行强制转换

>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]

此时,我们可以提取马克斯的位置

>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)

上面告诉我们,最大值在位置4,他的值是5。

如你所见,在key参数中,你可以通过定义适当的lambda来找到任何可迭代对象的最大值。

我希望它能有所帮助。

PD:正如@PaulOyster在评论中指出的那样。对于Python 3.xminmax允许一个新的关键字default,以避免在参数为空列表时引发异常ValueErrormax(enumerate(list), key=(lambda x:x[1]), default = -1)

这段代码不像之前发布的答案那么复杂,但它可以工作:

m = max(a)
n = 0    # frequency of max (a)
for number in a :
if number == m :
n = n + 1
ilist = [None] * n  # a list containing index values of maximum number in list a.
ilistindex = 0
aindex = 0  # required index value.
for number in a :
if number == m :
ilist[ilistindex] = aindex
ilistindex = ilistindex + 1
aindex = aindex + 1


print ilist

上面代码中的ilist将包含列表中最大数字的所有位置。

只有一句话:

idx = max(range(len(a)), key = lambda i: a[i])

@shash在其他地方回答了这个问题

找到最大列表元素的索引的python方法是

position = max(enumerate(a), key=lambda x: x[1])[0]

一个通过。然而,它比@Silent_Ghost的解决方案慢,甚至比@nmichaels的解决方案更慢:

for i in s m j n; do echo $i;  python -mtimeit -s"import maxelements as me" "me.maxelements_${i}(me.a)"; done
s
100000 loops, best of 3: 3.13 usec per loop
m
100000 loops, best of 3: 4.99 usec per loop
j
100000 loops, best of 3: 3.71 usec per loop
n
1000000 loops, best of 3: 1.31 usec per loop
>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1])
>>> (3, 32)
a = [32, 37, 28, 30, 37, 25, 27, 24, 35,
55, 23, 31, 55, 21, 40, 18, 50,
35, 41, 49, 37, 19, 40, 41, 31]


import pandas as pd


pd.Series(a).idxmax()


9

我通常都是这么做的。

你可以用不同的方法来做。

传统的方法是,

maxIndexList = list() #this list will store indices of maximum values
maximumValue = max(a) #get maximum value of the list
length = len(a)       #calculate length of the array


for i in range(length): #loop through 0 to length-1 (because, 0 based indexing)
if a[i]==maximumValue: #if any value of list a is equal to maximum value then store its index to maxIndexList
maxIndexList.append(i)


print(maxIndexList) #finally print the list

另一种不计算列表长度并将最大值存储到任何变量的方法是,

maxIndexList = list()
index = 0 #variable to store index
for i in a: #iterate through the list (actually iterating through the value of list, not index )
if i==max(a): #max(a) returns a maximum value of list.
maxIndexList.append(index) #store the index of maximum value
index = index+1 #increment the index


print(maxIndexList)

我们可以用python和聪明的方式来做!在一行中使用列表理解,

maxIndexList = [i for i,j in enumerate(a) if j==max(a)] #here,i=index and j = value of that index

我所有的代码都是Python 3的。

如果你想获取一个名为data的列表中最大的n数字的下标,你可以使用Pandas sort_values:

pd.Series(data).sort_values(ascending=False).index[0:n]

还有一个解决方案,它给出了只是第一次出现,可以通过使用numpy实现:

>>> import numpy as np
>>> a_np = np.array(a)
>>> np.argmax(a_np)
9

这里有一个简单的单步解决方案。

import math
nums = [32, 37, 28, 30, 37, 25, 55, 27, 24, 35, 55, 23, 31]


max_val = -math.inf
res = []


for i, val in enumerate(nums):
if(max_val < val):
max_val = val
res = [i]
elif(max_val == val):
res.append(i)
print(res)