Статьи

Как получить ключ с максимальным значением в Python-словаре?

Базовый Python

TL;DR

В большинстве ответов на этот вопрос в интернете говорится, что для этой цели нужно использовать отдельную библиотеку. Это не совсем так.
Для поиска в Python-словаре ключа с максимальным значением можно использовать функцию max():
print(max(dict_, key=dict_.get))
Она вернёт ключ с максимальным значением, предварительно применив метод dict.get(k) ко всем ключам k для получения связанных с ними значений.

Рассмотрим простейший пример:
income = {
    'Иван': 20000,
    'Пётр': 25000,
    'Фёдор': 100000
}

print(max(income, key=income.get)) # Фёдор
Функция max() перебирает все ключи k в словаре income и после применения метода income.get(k) выбирает тот, что имеет максимальное значение. При этом метод get() возвращает значение, соответствующее ключу k в словаре income.

Что такое функция max() в Python?

Скорее всего, данная функция уже вам знакома. С её помощью можно находить максимальное значение в любом итерируемом объекте или среди любого количества различных значений.
Функция max() возвращает максимальное значение из всех, которые были в неё переданы. В качестве аргументов можно передавать произвольное количество значений через запятую, либо же итерируемый объект. Необязательный аргумент key позволяет настроить способ вычисления максимального значения. Это правило преобразования, которое будет предварительно применено к каждому элементу.
Сперва рассмотрим несколько небольших примеров без использования аргумента key.
income = {
    'Иван': 20000,
    'Пётр': 25000,
    'Фёдор': 100000
}

# Ключ, начинающийся с "наибольшей" буквы в алфавите
print(max(income))
# Фёдор

# Наибольшее значение в словаре income
print(max(income.values()))
# 100000

# Наибольший элемент в списке
print(max([1, 4, 7, 5, 3, 99, 3]))
# 99

# Сравнение списков по элементам.
# Максимальным списком считается тот,
# в котором содержится максимальное число.
# Если максимальное число встречается
# в нескольких списках, возвращается
# первый из них.
print(max([1, 2, 3], [5, 6, 4]))
# [5, 6, 4]

# Максимальное значение в переданной последовательности чисел
print(max(5, 7, 99, 88, 123))
# 123
Пока всё понятно. Функция max() является довольной гибкой и позволяет работать не только с числами, но и в принципе с любыми сравниваемыми объектами, включая строки и списки.

Как работает аргумент key в функции max() в Python?

Последние примеры показывают интуитивно понятную работу функции max(): вы просто передаёте один или несколько итерируемых объектов в качестве позиционных аргументов.

Что такое итерируемые объекты?

Итерируемый объект — это объект, из которого вы можете получить итератор.
Итератор — это объект, для которого можно вызвать функцию next(). Вызывая её, вы получаете следующий элемент итерируемого объекта, пока они не закончатся в итераторе.
Например, Python использует итераторы в циклах for для перебора элементов в списке, символов в строке и ключей в словаре.
Когда вы указываете аргумент key, вы также определяете и функцию, возвращающую значение каждого элемента в итерируемом объекте. Далее каждый элемент сравнивается на основе значения, возвращаемого этой самой функцией, а не элементом итерируемого объекта (по умолчанию).
А вот и пример:
lst = [2, 4, 8, 16]

def inverse(val):
   return -val
   
print(max(lst)) # 16

print(max(lst, key=inverse)) # 2
Мы определяем функцию inverse(), которая возвращает умноженное на -1 входное значение.

Затем мы выводим два результата выполнения функции max():
  • первое — это выполнение функции по умолчанию. Максимальное значение в исходном списке равно 16, что и было выведено на экран.
  • во втором случае мы передаём функцию inverse() в качестве аргумента key. Python применяет данную функцию ко всем элементам списка lst и сравнивает между собой полученные значения. В итоге мы получаем элемент, значение которого оказалось максимальным после преобразования функцией key.

Используя функцию inverse(), Python сопоставляет значения следующим образом:
  • оригинальные значения: 2, 4, 8, 16.
  • значения после применения inverse(): -2, -4, -8, -16.

В итоге мы получаем число 2, которому соответствует преобразованное значение -2, потому что -2 > -4 > -8 > -16.

Теперь вернёмся к первоначальному вопросу.

Как получить ключ с максимальным значением в словаре Python?

Мы используем тот же пример, что и выше. В словаре хранятся данные о доходах трёх человек: Ивана, Петра и Фёдора. Предположим, что вы хотите найти человека с самым высоким доходом.
Совет: ключ словаря и параметр key называются одинаково, но путать их нельзя — между ними нет ничего общего.
Из задачи мы знаем, что результатом должен быть ключ словаря, поэтому вызовем функцию max() именно по ключам словаря income. Обратите внимание, что max(income.keys()) и max(income) возвращают один и тот же результат.

Однако, мы хотим сравнить значения, а не ключи. Для этого мы будем использовать параметр key в функции max(). Мы должны передать в него функцию, но какую?

Чтобы получить значение ключа 'Иван', мы можем использовать обозначение в скобках — income['Иван']. Однако, это не является функцией, а значит не будет работать.

К счастью, есть метод income.get('Иван') похож на income['Иван']! Единственное отличие между ними заключается в том, что метод get() возвращает значение None, если указанного ключа нет в словаре.

Итак, мы передадим этот метод в аргумент key функции max().
income = {
    'Иван': 20000,
    'Пётр': 25000,
    'Фёдор': 100000
}

print(max(income, key=income.get)) # Фёдор

Как получить ключ с минимальным значением в словаре?

Если вы усвоили предыдущие примеры, поиск минимального значения не станет для вас чем-то сложным. Для этого достаточно заменить функцию max() на функцию min():
income = {
    'Иван': 20000,
    'Пётр': 25000,
    'Фёдор': 100000
}

print(min(income, key=income.get)) # Иван

Альтернативные методы поиска максимального значения в словаре

Использование функции max() — далеко не единственный способ найти максимальное значение. Пользователь со StackOverflow сравнил между собой 9 различных методов решения данной задачи.
# Конвертация словаря в списки + index(max())
def f1(): 
    v=list(income.values())
    k=list(income.keys())
    return k[v.index(max(v))]

# Dictionary comprehension, чтобы поменять ключи и значения местами
def f2():
   d3={v:k for k,v in income.items()}
   return d3[max(d3)]

# filter() + lambda-функция
def f3():
   return list(filter(lambda t: t[1]==max(income.values()), income.items()))[0][0]   

# Как f3(), но более компактный
def f4():
   m=max(income.values())
   return list(filter(lambda t: t[1]==m, income.items()))[0][0] 
      
# List comprehension
def f5():
   return [k for k,v in income.items() if v==max(income.values())][0]  
 
# Как и f5(), только без max() в comprehension
def f6():
   m=max(income.values())
   return [k for k,v in income.items() if v==m][0]   
    
# Метод из этой статьи
def f7():
   return max(income, key=income.get)    

# Укороченная версия f1()
def f8():
    v=list(income.values())
    return list(income.keys())[v.index(max(v))] 
  
# f7(), но с использованием lambda-функции
def f9():
    return max(income, key=lambda k: income[k])    

print(f1())
print(f2())
print(f3())
print(f4())
print(f5())
print(f6())
print(f7())
print(f8())
print(f9())
# Фёдор (везде)
f1() работает наиболее быстро.

Второй по эффективности метод:
income = {
    'Иван': 20000,
    'Пётр': 25000,
    'Фёдор': 100000
}

v = list(income.values())
k = list(income.keys())

print(k[v.index(max(v))]) # Фёдор

Поиск с ключа с самым длинным значением в словаре

Мы знаем, как искать максимальное значение, если эти самые значения являются числами. Но что, если мы имеем дело со строками или списками?
Предположим, что у нас есть словарь, где записано количество дней, которые отработал каждый сотрудник. На конец месяца он будет выглядеть примерно так:
days_worked = {
    'Иван': [1, 1, 1, 1], 
    'Пётр': [1, 1, 1, 1, 1, 1], 
    'Фёдор': [1, 1, 1, 1, 1, 1, 1, 1]
}
Общее количество отработанных дней равно длине списка соответствующего сотрудника. В нашем случае элементы всех списков одинаковы, поэтому сравнивать списки мы будем именно по их длине.
# Длина 2 меньше, чем длина 4
print([1, 1] < [1, 1, 1, 1]) # True
Таким образом, мы можем использовать уже знакомый код для поиска максимального значения.
print(max(days_worked, key=days_worked.get)) # 'Фёдор'

Поиск ключа с максимальным значением в списке словарей

Допустим, у нас есть три словаря с информацией о доходах. Мы хотим найти ключ с максимальным значением из всех словарей.
income1 = {'Иван': 1111,
           'Пётр': 2222,
           'Фёдор': 3333}

income2 = {'Данил': 4444,
           'Анастасия': 5555,
           'Филипп': 6666}

income3 = {'Григорий': 7777,
           'Захар': 8888,
           'Игорь': 999999999999}

list_of_dicts = [income1, income2, income3]
Мы видим, что самым высоким доходом обладает Игорь. Следовательно, этот ключ и будет возвращён. Есть несколько способов этого добиться.

Чтобы найти ключ с максимальным значением среди списка словарей, необходимо объединить словари в один большой словарь с помощью метода dict.update(), а затем использовать знакомую нам функцию max(d, key = d.get). Рассмотрим пример:
# Инициализируем пустой словарь
big_dict = {}

# Используем цикл for и метод update() для добавления пар ключ-значение
for dic in list_of_dicts:
        big_dict.update(dic)

# Проверяем, что результат соответствует ожиданиям
print(big_dict)

{'Иван': 1111,
'Пётр': 2222,
'Фёдор': 3333,
'Данил': 4444,
'Анастасия': 5555,
'Филипп': 6666,
'Григорий': 7777,
'Захар': 8888,
'Игорь': 999999999999}

# Вызываем функцию max() и указываем аргумент key
print(max(big_dict, key=big_dict.get)) # 'Игорь' 

Как получить максимальное значение в словаре Python?

Чтобы получить максимальное значение в словаре d, воспользуйтесь функцией max(d.values()). Сначала она получает итерируемый объект всех значений словаря с помощью d.values(), который затем передаётся в max(). Функция max() выбирает единственное максимальное значение.
В следующем примере мы получаем максимальное целочисленное значение из всех значений словаря.
d = {'Иван': 24,
     'Пётр': 19,
     'Фёдор': 35}

max_val = max(d.values())

print(max_val) # 35

Как получить максимальный ключ в словаре Python?

Для этого достаточно использовать max(d) или max(d.keys()) — оба варианта эквивалентны, потому что передают итерируемый объект ключей в функцию max(), которая выбирает из них максимальный.
Пример получения максимальной строки из ключей словаря:
d = {'Иван': 24,
     'Пётр': 19,
     'Фёдор': 35}

print(max(d)) # 'Фёдор'

print(max(d.keys())) # 'Фёдор'

Заключение

Теперь вы лучше разбираетесь в работе со словарями Python. В частности, мы попробовали разными способами получать максимальные и минимальные ключи и их значения.
Спасибо за внимание!

Источник: Finxter