Как argmax должен быть реализован в Python? Он должен быть максимально эффективным, поэтому он должен работать с итерациями.
Три способа реализации:
f
f(key)
Я изменил лучшее решение, которое нашел:
# given an iterable of pairs return the key corresponding to the greatest value def argmax(pairs): return max(pairs, key=lambda x: x[1])[0] # given an iterable of values return the index of the greatest value def argmax_index(values): return argmax(enumerate(values)) # given an iterable of keys and a function f, return the key with largest f(key) def argmax_f(keys, f): return max(keys, key=f)
Является ли следующий код быстрым и питонским?
idx_max = max(enumerate(x), key=lambda x:x[1])[0]
Мне было проще думать об argmax: скажем, мы хотим вычислить argmax(f(y)), где y - элемент из Y. Таким образом, для каждого y мы хотим вычислить f(y) и получить y с максимальным f(y).
argmax(f(y))
y
Y
f(y)
Это определение argmax является общим, в отличие от "если итерируемые значения возвращают индекс наибольшего значения" (и это также вполне естественно ИМХО).
And ..drumroll .. Python позволяет делать это с помощью встроенного max:
max
best_y = max(Y, key=f)
То есть argmax_f (из принятого ответа) излишне сложен и неэффективен ИМХО - это сложный вариант встроенного max. Все остальные argmax-подобные задачи должны проясниться на этом этапе: просто определите правильную функцию f.
argmax_f
На основе ответа Нейла, но специализируется на функциях, которые принимают несколько аргументов.
argmax = lambda keys, func: max(imap(lambda key: (func(*key), key), keys))[1]
Например:
argmax([(5, 2), (3, 3), (2, 5)], pow) # (2, 5)
def argmax(lst): return lst.index(max(lst))
или аналогично:
argmax = lambda lst: lst.index(max(lst)