Pythonic способ найти максимальное значение и его индекс в списке?

Если мне нужно максимальное значение в списке, я могу просто написать max(List), но что, если мне также нужен индекс максимального значения?

Я могу написать что-то вроде этого:

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

Но мне это выглядит скучно.

И если я пишу:

List.index(max(List))

Затем он дважды перебирает список.

Есть ли лучший способ?

Ответ 1

Существует много вариантов, например:

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

Ответ 2

Я думаю, что принятый ответ велик, но почему бы вам не сделать это явно? Я чувствую, что больше людей поймут ваш код, и это согласуется с 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

Ответ 3

Этот ответ в 33 раза быстрее, чем @Escualo, предполагая, что список очень велик и предполагается, что он уже является np.array(). Мне пришлось отказаться от количества тестовых прогонов, потому что тест смотрит на 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

Ответ 4

Со встроенной библиотекой 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], которая говорит, что 0 фактически равен 2, 1 - это на самом деле 9 и т.д.

Ответ 5

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

Ответ 6

Я бы предложил очень простой способ:

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

Надеюсь, поможет.

Ответ 7

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)]

Ответ 8

извините за возрождение этой темы, но думал, что мой метод стоит добавить.

Имя списка в этом примере "список"

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

Это напечатает самое высокое значение в списке просто как!

list.sort() сортирует список по значению элемента в таблице ASCII, поэтому эффективно сортирует список по возрастанию. Затем я просто печатаю последнее значение в списке (которое будет наибольшим числом) с помощью print(list[-1]).

Надеюсь это поможет!

Ответ 9

Может быть, вам нужен отсортированный список?

Попробуйте следующее:

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])

Ответ 10

У меня есть список, состоящий из нескольких словарей внутри. и каждый словарь имеет свои значения в виде списка, состоящего из 2 значений. Теперь я хочу найти максимальное значение из каждого словаря и минимальное значение из каждого словаря. 2-й элемент списка в качестве значения тоже должен учитываться.

Ответ 11

Вот полное решение вашего вопроса с использованием встроенных функций 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)