Python 如何在列表中找到最大值的所有位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3989016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find all positions of the maximum value in a list?
提问by Bob
I have a 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]
max element is 55 (two elements on position 9 and 12)
最大元素为 55(位置 9 和 12 上的两个元素)
I need to find on which position(s) the maximum value is situated. Please, help.
我需要找到最大值位于哪个位置。请帮忙。
采纳答案by SilentGhost
>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]
回答by nmichaels
a.index(max(a))
will tell you the index of the first instance of the largest valued element of list a.
将告诉您 list 的最大值元素的第一个实例的索引a。
回答by hughdbrown
Here is the max value and the indexes it appears at:
这是最大值及其出现的索引:
>>> 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]
Later: for the satisfaction of @SilentGhost
后来:为了@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]
回答by martineau
The chosen answer (and most others) require at least two passes through the list.
Here's a one pass solution which might be a better choice for longer lists.
选择的答案(和大多数其他答案)需要至少两次通过列表。
这是一个一次性解决方案,它可能是更长列表的更好选择。
Edited:To address the two deficiencies pointed out by @John Machin. For (2) I attempted to optimize the tests based on guesstimated probability of occurrence of each condition and inferences allowed from predecessors. It was a little tricky figuring out the proper initialization values for max_valand max_indiceswhich worked for all possible cases, especially if the max happened to be the first value in the list — but I believe it now does.
编辑:解决@John Machin 指出的两个缺陷。对于(2),我尝试根据每个条件的估计发生概率和前辈允许的推断来优化测试。这是一个有点棘手搞清楚正确的初始值max_val和max_indices其工作了所有可能的情况下,特别是在最大碰巧在列表中的第一个值-但我相信它现在。
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
回答by John Machin
I can't reproduce the @SilentGhost-beating performance quoted by @martineau. Here's my effort with comparisons:
我无法重现@martineau 引用的 @SilentGhost-beating 性能。这是我的比较努力:
=== maxelements.py ===
=== 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
Results from a beat-up old laptop running Python 2.7 on Windows XP SP3:
在 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
回答by John Machin
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])
回答by Salvador Dali
Similar idea with a list comprehension but without enumerate
具有列表理解但没有枚举的类似想法
m = max(a)
[i for i in range(len(a)) if a[i] == m]
回答by user3569257
You can also use the numpy package:
您还可以使用 numpy 包:
import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))
This will return an numpy array of all the indices that contain the max value
这将返回包含最大值的所有索引的 numpy 数组
if you want to turn this to a list:
如果你想把它变成一个列表:
maximum_indices_list = maximum_indices.tolist()
回答by jonaprieto
I came up with the following and it works as you can see with max, minand others functions over lists like these:
我想出了以下内容,它的工作原理如您所见max,min还有其他功能在这些列表上:
So, please consider the next example list find out the position of the maximumin the list a:
所以,请考虑下面的例子列表中找到了位置最大列表a:
>>> a = [3,2,1, 4,5]
Using the generatorenumerateand making a casting
使用发电机enumerate并制作铸件
>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]
At this point, we can extract the position of maxwith
在这一点上,我们可以提取的位置最大值与
>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)
The above tells us, the maximum is in the position 4 and his value is 5.
上面告诉我们,最大值在位置4,他的值为5。
As you see, in the keyargument, you can find the maximum over any iterable object by defining a lambda appropriate.
如您所见,在key参数中,您可以通过定义合适的 lambda 来找到任何可迭代对象的最大值。
I hope that it contributes.
我希望它有所贡献。
PD: As @PaulOyster noted in a comment. With Python 3.xthe minand maxallow a new keyword defaultthat avoid the raise exception ValueErrorwhen argument is empty list. max(enumerate(list), key=(lambda x:x[1]), default = -1)
PD:正如@PaulOyster 在评论中指出的那样。随着Python 3.x中min和max允许新的关键字default是避免引发异常ValueError时的说法是空列表。max(enumerate(list), key=(lambda x:x[1]), default = -1)
回答by Sukrit Gupta
This code is not as sophisticated as the answers posted earlier but it will work:
这段代码不像之前发布的答案那么复杂,但它可以工作:
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
ilistin the above code would contain all the positions of the maximum number in the list.
上面代码中的ilist将包含列表中最大数字的所有位置。

