如何在列表中find最大值的所有位置?
我有一个列表:
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上的两个元素)
我需要find最大值位于哪个位置。 请帮忙。
>>> m = max(a) >>> [i for i, j in enumerate(a) if j == m] [9, 12]
a.index(max(a))
会告诉你列表a
的最大值元素的第一个实例的索引。
select的答案(和大多数人)至less需要两次通过列表。
这是一个一个通过的解决scheme,这可能是更长的名单更好的select。
编辑:解决@John Machin指出的两个缺陷。 对于(2)我试图根据猜测的每个条件出现的概率和前人所允许的推论来优化testing。 为max_val
和max_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跳动的performance。 这是我比较的努力:
=== 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
我想出了以下内容,它可以像max
, min
和其他函数一样在列表中看到:
那么请考虑下列例子列表中找出列表a
最大的位置:
>>> a = [3,2,1, 4,5]
使用生成器 enumerate
和铸造
>>> list(enumerate(a)) [(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]
在这一点上,我们可以提取max的位置
>>> max(enumerate(a), key=(lambda x: x[1])) (4, 5)
以上告诉我们,最大的是位置4,他的值是5。
正如您所看到的,在key
参数中,您可以通过定义适当的lambda来find任何可迭代对象的最大值。
我希望它有所贡献。
PD:正如@PaulOyster在评论中指出的那样。 在Python 3.x
, min
和max
允许一个新的关键字default
,避免当参数为空列表时引发exceptionValueError
。 max(enumerate(list), key=(lambda x:x[1]), default = -1)
你也可以使用numpy包:
import numpy as np A = np.array(a) maximum_indices = np.where(A==max(a))
这将返回包含最大值的所有索引的numpy数组
如果你想把它变成一个列表:
maximum_indices_list = maximum_indices.tolist()
>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1]) >>> (3, 32)
以下是最大值及其出现的索引:
>>> 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]
只有一行:
idx = max(range(len(a)), key = lambda i: a[i])
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
我通常这样做。
与列表理解类似的概念,但没有列举
m = max(a) [i for i in range(len(a)) if a[i] == m]
@shash在别处回答了这个问题
Pythonic的方式来find最大列表元素的索引将是
position = max(enumerate(a), key=lambda x: x[1])[0]
哪一个通过 。 然而,它比@Silent_Ghost的解决scheme更慢,而@nmichaels更是如此:
for i in smjn; 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
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) 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将包含列表中最大数字的所有位置。
你可以用不同的方法做到这一点。
旧的传统方式是,
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
另一种不计算列表长度并将最大值存储到任何variables的方法,
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)
我们可以用Pythonic和聪明的方式做到这一点! 仅仅在一行中使用列表理解,
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]