min(iterable, *[, key, default]) min(arg1, arg2, *args[, key])
iterable - итерируемый объект,key - должна быть функцией (принимает один аргумент), используется для порядка сравнения элементов итерируемого объекта. Функция вычисляется один раз.default - значение по умолчанию, если итерируемый объект окажется пустым,arg1...argN - позиционный аргумент,*args - список позиционных аргументов.Функция min() возвращает минимальное значение элемента из итерируемого объекта или наименьшее из двух или более переданных позиционных аргументов.
sorted(iterable, key=keyfunc, reverse=True)[0] и heapq.nlargest(1, iterable, key=keyfunc)Аргумент key - функция подобная той, которая используется в дополнительном методе списков list.sort(). Функция принимает один аргумент и используется для упорядочивания элементов.
>>> x = ['4', '11', '6', '31'] # функция `min` сравнивает # числа как строки >>> min(x) # '11' # функция 'key=lambda i: int(i)' применяется # к каждому элементу списка 'x', преобразуя # строки в тип 'int' и теперь функция `min` # сравнивает элементы списка как числа. >>> min(x, key=lambda i: int(i)) # '4' # или другое применение функции 'key' выбор # списка с наименьшей суммой элементов >>> min([1,2,3,4], [3,4,5], key=sum) # [1,2,3,4]
Аргумент default по умолчанию указывает объект, который нужно вернуть, если итерируемый объект пуст. Если итерация пуста и значение по умолчанию не указано, то возникает ошибка ValueError.
# Значение по умолчанию >>> min([], default=0) # 0 >>> min([]) # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # ValueError: min() arg is an empty sequence
Функция min() сравнивает элементы, используя оператор <. Поэтому, все передаваемые в них значения должны быть сопоставимы друг с другом и одного типа, иначе бросается исключение TypeError
При передаче в качестве аргумента [текстовых строк][t-str], [байтовых строк][t-bytes] или [байтовых массивов][t-bytearray], а так же списка символов, минимальное значение будет выбираться исходя из порядка следования символов, в таблице соответствующей кодировки.
>>> x = list('abcdifgh') >>> min(x) # 'a'
Изменено в Python 3.8: Аргумент key может быть None.
# использование позиционных аргументов >>> min(5, 3, 6, 5, 6) # 3 # использование в качестве аргумента списка >>> min([1.2, 1.3, 1.5, 2, 5.52]) # 1.2 # комбинирование позиционных аргументов и списка # при передаче списка 'x' происходит его распаковка >>> x = (1.2, 1.3, 1.5, 2, 5.52) >>> min(5, 3, 5, *x) # 1.2
Найдем самую короткую строку. В качестве ключа используем функцию len(). Она посчитает количество символов в строке каждого переданного позиционного аргумента, а функция min() выберет минимальное число. Строки можно передать например списком ['Jul', 'John', 'Vicky'], результат будет тот же.
>>> min('Jul', 'John', 'Vicky', key=len) # 'Jul'
min() в списке строк, записанных как целые числаЕсть список строк чисел и необходимо найти минимум, как если бы они были целыми числами? В первом случае функция min() выберет наименьшее значение списка исходя из лексикографической сортировки. Применим функцию lambda i: int(i) в качестве ключа key, которая преобразует строчные элементы списка в целые числа, тогда функция min() выберет то что нам нужно.
>>> x = ['4', '11', '6', '31'] # неправильное решение >>> min(x) # '11' # правильное решение >>> min(x, key = lambda i: int(i)) # '4'
min() по второму элементу кортежа дляНапример есть список кортежей. По умолчанию будет выбираться кортеж, у которого минимальное значение имеет первый элемент. Но мы хотим получить кортеж, у которого наименьшее значение имеет второй элемент! Для этого применим лямбда-функцию lambda i : i[1] в качестве ключа key, которая укажет функции min(), из каких элементов кортежа выбирать минимальное значение.
>>> x = [(1,3), (2,4), (1,9), (4,1)] # происходит сравнение по # первым элементам кортежа >>> min(x) # (1,3) # меняем порядок сравнения >>> x = [(1,3), (2,4), (1,9), (4,1)] >>> min(x, key=lambda i : i[1]) # (4,1)
Допустим есть список чисел и стоит задача, определить индекс минимального значения в этом списке.
Для решения этой задачи необходимо пронумеровать список, т.е. создать кортеж - индекс/число, а затем найти минимум при помощи функции min(), а в качестве ключа этой функции использовать key=lambda i : i[1].
>>> lst = [5, 3, 1, 0, 9, 7] # пронумеруем список >>> lst_num = list(enumerate(lst, 0)) # получился список кортежей, в которых # первый элемент - это индекс значения списка, # а второй элемент - само значение списка >>> lst_num # [(0, 5), (1, 3), (2, 1), (3, 0), (4, 9), (5, 7)] # найдем минимум (из второго значения кортежей) >>> t_min = min(lst_num, key=lambda i : i[1]) >>> t_min # (3, 0) # индекс минимального значения списка >>> t_min[0] # 3
Это самый частый источник исключений.
values: list[int] = [] # Безопасно: вернёт 0 вместо ValueError m = min(values, default=0)
Важно:
default= нельзя использовать в форме min(a, b, c).key= вместо ручных цикловЭто и короче, и обычно читабельнее.
users = [ {"name": "Ann", "age": 30}, {"name": "Bob", "age": 25}, ] youngest = min(users, key=lambda u: u["age"]) # youngest -> {"name": "Bob", "age": 25}
По умолчанию min(d) сравнивает ключи.
scores = {"a": 50, "b": 10, "c": 30} # Минимальный ключ (лексикографически) min_key = min(scores) # Ключ с минимальным значением min_by_value_key = min(scores, key=scores.get) # Пара (ключ, значение) с минимальным значением min_item = min(scores.items(), key=lambda kv: kv[1])
keyЭто простой и мощный паттерн.
people = [ {"name": "Ann", "age": 30, "salary": 100}, {"name": "Bob", "age": 30, "salary": 90}, {"name": "Cat", "age": 25, "salary": 120}, ] # Сначала минимальный возраст, потом минимальная зарплата best = min(people, key=lambda p: (p["age"], p["salary"]))
Если критерии равны, min() возвращает первый встретившийся элемент.
Это полезно как неявный "стабильный" тай-брейк:
items = ["aa", "b", "cc"] m = min(items, key=len) # "b" - первое строка с минимальной длиной
В Python 3 нельзя сравнивать разные несопоставимые типы без key.
# min([1, "2"]) -> TypeError
Если нужны правила - задайте key или преобразуйте данные.
NaNПоведение может быть неожиданным:
import math data = [math.nan, 1.0, 2.0] m = min(data) # часто будет nan, если nan стоит первым
Если данные могут содержать NaN, лучше фильтровать:
clean = [x for x in data if not math.isnan(x)] m = min(clean, default=math.nan)
from operator import attrgetter # быстрее и читабельнее, чем lambda для простого доступа к атрибутам youngest = min(users, key=attrgetter("age"))
values = [10, 3, 7] # Возвращает индекс элемента с минимальным значением min_index = min(range(len(values)), key=values.__getitem__) # min_index -> 1
Альтернатива с enumerate:
min_index, min_value = min(enumerate(values), key=lambda iv: iv[1])
Например, искать "самое раннее" имя без учёта регистра:
names = ["bob", "Ann", "cat"] m = min(names, key=str.lower) # "Ann"
def min_price(items: list[dict]) -> int | None: # None как сигнал "нет данных" return min((i["price"] for i in items), default=None)
key сложный и используется несколько раз, вынесите в именованную функцию.operator.itemgetter/attrgetter.keyed = [(f(x), x) for x in items] k_min, x_min = min(keyed, default=(None, None))
min() - базовый инструмент для декларативного поиска минимального элемента.Почти все лучшие практики сводятся к трём правилам:
default=).key= для смысла и читаемости.NaN).