在列表中找到最大值及其索引的Pythonic方法?

问题:在列表中找到最大值及其索引的Pythonic方法?

如果我想要列表中的最大值,我可以只写max(List),但是如果我还需要最大值的索引怎么办?

我可以这样写:

maximum=0
for i,value in enumerate(List):
    if value>maximum:
        maximum=value
        index=i

但这对我来说很乏味。

如果我写:

List.index(max(List))

然后它将迭代列表两次。

有没有更好的办法?

If I want the maximum value in a list, I can just write max(List), but what if I also need the index of the maximum value?

I can write something like this:

maximum=0
for i,value in enumerate(List):
    if value>maximum:
        maximum=value
        index=i

But it looks tedious to me.

And if I write:

List.index(max(List))

Then it will iterate the list twice.

Is there a better way?


回答 0

有很多选项,例如:

import operator
index, value = max(enumerate(my_list), key=operator.itemgetter(1))

There are many options, for example:

import operator
index, value = max(enumerate(my_list), key=operator.itemgetter(1))

回答 1

我认为公认的答案很好,但是为什么不明确地做呢?我感觉更多的人会理解您的代码,这与PEP 8一致:

max_value = max(my_list)
max_index = my_list.index(max_value)

此方法也比接受的答案快三倍:

import random
from datetime import datetime
import operator

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

if __name__ == "__main__":
    from timeit import Timer
    t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Explicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

    t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Implicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

结果在我的计算机上运行:

Explicit: 8.07 usec/pass
Implicit: 22.86 usec/pass

其他套装:

Explicit: 6.80 usec/pass
Implicit: 19.01 usec/pass

I think the accepted answer is great, but why don’t you do it explicitly? I feel more people would understand your code, and that is in agreement with PEP 8:

max_value = max(my_list)
max_index = my_list.index(max_value)

This method is also about three times faster than the accepted answer:

import random
from datetime import datetime
import operator

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

if __name__ == "__main__":
    from timeit import Timer
    t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Explicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

    t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Implicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

Results as they run in my computer:

Explicit: 8.07 usec/pass
Implicit: 22.86 usec/pass

Other set:

Explicit: 6.80 usec/pass
Implicit: 19.01 usec/pass

回答 2

假设列表很大,并且假设它已经是np.array(),那么这个答案比@Escualo快33倍。我不得不拒绝测试运行的次数,因为该测试所关注的是10000000个元素,而不仅仅是100个。

import random
from datetime import datetime
import operator
import numpy as np

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

def npmax(l):
    max_idx = np.argmax(l)
    max_val = l[max_idx]
    return (max_idx, max_val)

if __name__ == "__main__":
    from timeit import Timer

t = Timer("npmax(l)", "from __main__ import explicit, implicit, npmax; "
      "import random; import operator; import numpy as np;"
      "l = np.array([random.random() for _ in xrange(10000000)])")
print "Npmax: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Explicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Implicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

我计算机上的结果:

Npmax: 8.78 msec/pass
Explicit: 290.01 msec/pass
Implicit: 790.27 msec/pass

This answer is 33 times faster than @Escualo assuming that the list is very large, and assuming that it’s already an np.array(). I had to turn down the number of test runs because the test is looking at 10000000 elements not just 100.

import random
from datetime import datetime
import operator
import numpy as np

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

def npmax(l):
    max_idx = np.argmax(l)
    max_val = l[max_idx]
    return (max_idx, max_val)

if __name__ == "__main__":
    from timeit import Timer

t = Timer("npmax(l)", "from __main__ import explicit, implicit, npmax; "
      "import random; import operator; import numpy as np;"
      "l = np.array([random.random() for _ in xrange(10000000)])")
print "Npmax: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Explicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Implicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

Results on my computer:

Npmax: 8.78 msec/pass
Explicit: 290.01 msec/pass
Implicit: 790.27 msec/pass

回答 3

使用Python的内置库,非常简单:

a = [2, 9, -10, 5, 18, 9] 
max(xrange(len(a)), key = lambda x: a[x])

这告诉max[0, 1, 2, ..., len(a)]使用自定义函数查找列表中最大的数字,该函数lambda x: a[x]表示0is 21is 9等等。

With Python’s built-in library, it’s pretty easy:

a = [2, 9, -10, 5, 18, 9] 
max(xrange(len(a)), key = lambda x: a[x])

This tells max to find the largest number in the list [0, 1, 2, ..., len(a)], using the custom function lambda x: a[x], which says that 0 is actually 2, 1 is actually 9, etc.


回答 4

max([(v,i) for i,v in enumerate(my_list)])
max([(v,i) for i,v in enumerate(my_list)])

回答 5

我建议一种非常简单的方法:

import numpy as np
l = [10, 22, 8, 8, 11]
print(np.argmax(l))
print(np.argmin(l))

希望能帮助到你。

I would suggest a very simple way:

import numpy as np
l = [10, 22, 8, 8, 11]
print(np.argmax(l))
print(np.argmin(l))

Hope it helps.


回答 6

max([(value,index) for index,value in enumerate(your_list)]) #if maximum value is present more than once in your list then this will return index of the last occurrence

如果当前的最大值不止一次并且您想要获取所有索引,

max_value = max(your_list)
maxIndexList = [index for index,value in enumerate(your_list) if value==max(your_list)]
max([(value,index) for index,value in enumerate(your_list)]) #if maximum value is present more than once in your list then this will return index of the last occurrence

If maximum value in present more than once and you want to get all indices,

max_value = max(your_list)
maxIndexList = [index for index,value in enumerate(your_list) if value==max(your_list)]

回答 7

也许您仍然需要一个排序列表?

试试这个:

your_list = [13, 352, 2553, 0.5, 89, 0.4]
sorted_list = sorted(your_list)
index_of_higher_value = your_list.index(sorted_list[-1])

Maybe you need a sorted list anyway?

Try this:

your_list = [13, 352, 2553, 0.5, 89, 0.4]
sorted_list = sorted(your_list)
index_of_higher_value = your_list.index(sorted_list[-1])

回答 8

很抱歉恢复了该线程,但认为我的方法值得添加。

此示例中的列表名称为“列表”

list.sort()
print(list[-1])

这将轻松打印列表中的最高值!

list.sort()ASCII表中项目的值对列表进行排序,因此有效地对列表进行从低到高的排序。然后,我只需使用即可打印列表中的最后一个值(这将是最大的数字)print(list[-1])

希望这可以帮助!

sorry for reviving this thread, but thought my method was worth adding.

The list name in this example ‘list’

list.sort()
print(list[-1])

That will print the highest value in the list easy as!

list.sort() sorts the list by the value of the item in the ASCII table, so effectively sorts the list lowest to highest. I then just print the last value in the list (which will be the greatest number) by using print(list[-1]).

Hope this helps!


回答 9

这是使用Python的内置函数为您的问题提供的完整解决方案:

# Create the List
numbers = input("Enter the elements of the list. Separate each value with a comma. Do not put a comma at the end.\n").split(",") 

# Convert the elements in the list (treated as strings) to integers
numberL = [int(element) for element in numbers] 

# Loop through the list with a for-loop

for elements in numberL:
    maxEle = max(numberL)
    indexMax = numberL.index(maxEle)

print(maxEle)
print(indexMax)

Here is a complete solution to your question using Python’s built-in functions:

# Create the List
numbers = input("Enter the elements of the list. Separate each value with a comma. Do not put a comma at the end.\n").split(",") 

# Convert the elements in the list (treated as strings) to integers
numberL = [int(element) for element in numbers] 

# Loop through the list with a for-loop

for elements in numberL:
    maxEle = max(numberL)
    indexMax = numberL.index(maxEle)

print(maxEle)
print(indexMax)