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

Bob*_*Bob 128 python list max

我有一个清单:

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]
Run Code Online (Sandbox Code Playgroud)

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

我需要找到最大值位于哪个位置.请帮忙.

nmi*_*els 276

a.index(max(a))
Run Code Online (Sandbox Code Playgroud)

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

  • 我确实提到它只会给出第一个实例.如果你想要所有这些,SilentGhost的解决方案更漂亮,更不容易出错. (9认同)
  • 这只会让你获得第一个实例,并且他要求找到找到最大值的所有索引.您必须使用切片循环使用切片以获取每种情况下的剩余列表,并在不再找到它时处理异常. (6认同)
  • 至少在我遇到它时,问题明确要求在多个最大值的情况下列表... (5认同)
  • 从技术上讲,您可以使用它来获取最大值元素的第一个实例,然后将其设置为一个大得离谱的负数,然后找到下一个最大值元素,但这太复杂了。 (2认同)
  • 它明确表示“全部”。请不要发送垃圾邮件,这里的目标是尽快帮助人们不要获得徽章和声誉(如果您真的想提供帮助,请删除您的答案)。 (2认同)

Sil*_*ost 189

>>> m = max(a)
>>> [i for i, j in enumerate(a) if j == m]
[9, 12]
Run Code Online (Sandbox Code Playgroud)

  • @radtek big O 只是 n。在大 O 中忽略领先系数 (6认同)
  • 如果您不介意在列表中进行多次传递,那么很简短的答案 - 很可能. (4认同)
  • 理论上 O(N) 和 O(2N) 是相同的,但实际上,O(N) 肯定会有更短的运行时间,尤其是当 N 接近无穷大时。 (2认同)

mar*_*eau 18

选择的答案(以及大多数其他答案)需要至少两次通过列表.
这是一个通过的解决方案,对于更长的列表可能是更好的选择.

编辑:解决@John Machin指出的两个缺陷.对于(2)我试图根据每个条件的发生概率和前辈允许的推论来优化测试.找出适当的初始化值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
Run Code Online (Sandbox Code Playgroud)

  • (1)空列表处理需要注意.应该返回广告的"[]"("返回列表").代码应该只是`如果不是seq:return []`.(2)循环中的测试方案是次优的:在随机列表中的平均值,条件`val <maxval`将是最常见的,但上面的代码需要2次测试而不是1次. (4认同)

Gre*_*een 12

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

>>> import numpy as np
>>> a_np = np.array(a)
>>> np.argmax(a_np)
9
Run Code Online (Sandbox Code Playgroud)


Joh*_*hin 8

我无法重现@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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)


jon*_*eto 7

我提出了以下内容,它可以正常运行max,min其他功能可以通过以下列表运行:

所以,请考虑下面的例子列表中找到了位置最大列表a:

>>> a = [3,2,1, 4,5]
Run Code Online (Sandbox Code Playgroud)

使用发电机 enumerate并制作铸件

>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]
Run Code Online (Sandbox Code Playgroud)

在这一点上,我们可以提取的位置最大值

>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)
Run Code Online (Sandbox Code Playgroud)

以上告诉我们,最大值位于第4位,其值为5.

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

我希望它有所贡献.

PD:正如@PaulOyster在评论中指出的那样.随着Python 3.xminmax允许新的关键字default是避免引发异常ValueError时的说法是空列表.max(enumerate(list), key=(lambda x:x[1]), default = -1)

  • 这是一个更好的解决方案,因为它涉及单次传递。不过有几点意见: 1. 不需要 list() 枚举,2. lambda 最好用括号括起来, 3. min() 和 max() 现在有一个默认参数(在空输入时返回),所以可以使用它(例如,默认值=-1)以避免 ValueError 异常,并且 4. 请更改为 max(),因为这是原始问题。 (3认同)
  • 当它在列表中出现多次时,只会发现其中一个最大价值元素(第一个)的位置,因此无法回答所提出的问题。 (2认同)

小智 7

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
Run Code Online (Sandbox Code Playgroud)

这就是我通常这样做的方式.


小智 6

您还可以使用numpy软件包:

import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))
Run Code Online (Sandbox Code Playgroud)

这将返回一个包含最大值的所有索引的numpy数组

如果要将其转到列表:

maximum_indices_list = maximum_indices.tolist()
Run Code Online (Sandbox Code Playgroud)


ser*_*inc 5

@shash 在别处回答了这个问题

查找最大列表元素索引的 Pythonic 方法是

position = max(enumerate(a), key=lambda x: x[1])[0]
Run Code Online (Sandbox Code Playgroud)

一个通过了。然而,它比 @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
Run Code Online (Sandbox Code Playgroud)


Har*_*han 5

>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1])
>>> (3, 32)
Run Code Online (Sandbox Code Playgroud)