Max и min в python

Предположим, что есть вложенный список, например:

При вызове функции min() :

Почему и как это работает? Каковы некоторые его варианты использования?

Как списки и другие последовательности сравниваются в Python?

Списки (и другие последовательности) в Python сравниваются лексикографически и не основаны ни на каком другом параметре.

Объекты последовательности могут сравниваться с другими объектами с тем же типом последовательности. Сравнение использует лексикографическое упорядочение: сначала сравниваются первые два элемента, и если они отличаются друг от друга, это определяет результат сравнения; если они равны, сравниваются следующие два элемента и так далее, пока не будет исчерпана любая последовательность.

Что такое лексикографическая сортировка?

лексикографический или лексикографический порядок (также известный как лексический порядок, словарьный порядок, алфавитный порядок или лексикографический (al) продукт) является обобщением того, как алфавитный порядок слов основан на алфавитном порядке их составляющих букв.

Функция min возвращает наименьшее значение в iterable. Таким образом, лексикографическое значение [1,2] является наименьшим в этом списке. Вы можете проверить, используя [1,2,21]

Что происходит в этом случае min ?

Переход на элемент my_list , во-первых, [1,2,21] и [1,3] . Теперь из документов

Если два элемента, которые нужно сравнить, сами являются последовательностями одного и того же типа , лексикографическое сравнение выполняется рекурсивно .

Таким образом, значение [1,1,21] меньше [1,3] , потому что второй элемент [1,3] , который равен 3 , лексикографически выше значения второго элемента [1,1,21] , который, 1 .

Теперь сравниваем [1,2] и [1,2,21] и добавляем еще одну ссылку из документов

Если одна последовательность представляет собой начальную подпоследовательность другой, более короткая последовательность представляет собой меньшую (меньшую).

[1,2] — начальная подпоследовательность [1,2,21] . Поэтому значение [1,2] в целом меньше, чем значение [1,2,21] . Следовательно, в качестве вывода возвращается [1,2] .

Это можно проверить с помощью функции sorted

Что делать, если в списке есть несколько минимальных элементов?

Если список содержит повторяющиеся минимальные элементы, возвращается первый

Это можно подтвердить, используя вызов функции id

Что мне нужно сделать для предотвращения лексикографического сравнения в min ?

Если требуемое сравнение не является лексикографическим, можно использовать аргумент key (как указано Padraic)

Функция min имеет дополнительный необязательный аргумент key . Аргумент key принимает функцию.

Необязательный ключевой аргумент указывает функцию упорядочения с одним аргументом как и для list.sort() . Ключевой аргумент, если он поставлен, должен быть в форме ключевого слова (например, min(a,b,c,key=func) ).

Например, если нам нужен наименьший элемент по длине, нам нужно использовать функцию len .

Как мы видим, здесь возвращается первый самый короткий элемент.

Что делать, если список неоднороден?

Если список является гетерогенным , имена типов рассматриваются для заказа, проверьте Сравнения,

Объекты разных типов, кроме чисел, упорядочиваются по именам типов

Следовательно, если вы поместите int и list , вы получите целочисленное значение как наименьшее, так как i имеет меньшее значение, чем l . Аналогично ‘1’ будет иметь более высокую ценность, чем обе эти.

Python3 и далее

Однако эта запутанная техника была удалена в Python3. Теперь он вызывает TypeError . Прочитайте Что нового в Python 3.0

Операторы сравнения порядка ( , , >= , > ) создают исключение TypeError , когда операнды не имеют значимого естественного упорядочения. Таким образом, выражения типа 1 , 0 > None или len более недействительны и, например, None вызывает TypeError вместо возврата False . Следствием является то, что сортировка гетерогенного списка больше не имеет смысла — все элементы должны быть сопоставимы друг с другом .

Но он работает для типов Comparable, например

Здесь мы видим, что list содержит значения float и int . Но поскольку float и int являются сопоставимыми типами, в этом случае работает функция min .

В языке программирования Python есть встроенные функции поиска минимума и максимума. Им можно передавать как один объект, так и непосредственно множество однотипных объектов. Если передается один объект, то им может быть список, любая другая коллекция или итерируемый объект.

Если передается один список, то в нем находится минимум или максимум, которые возвращаются функциями min() и max().

Если передается несколько списков, то целиком возвращается один из переданных списков. При этом сравнение происходит поэлементно: сначала сравниваются первые элементы списков. Если они не равны, то функция min() вернет тот список, первый элемент которого меньше, max() — наоборот. Если первые элементы равны, то будут сравниваться вторые и т. д.

Функциям min() и max() можно непосредственно передавать множество чисел:

Таким образом, если функции получают несколько объектов, то сравниваются сами объекты. И неважно какого они типа: списки, числа или что-то другое.

Однако нельзя передать числа и строки или смешанный список. В этом случае функция возвращает ошибку:

В функциях min() и max() можно указать необязательный именной параметр key. Ему присваивается одноаргументная функция, которая выполняет какое-то предварительное действие над элементами списка.

Здесь во втором случае находится максимум среди абсолютных значений чисел. То есть к каждому элементу списка применяется встроенная в Python функция abs(). Однако применить ее к целым спискам нельзя:

Подскажите пожалуйста, пытаюсь понять реализацию функции min/max. Мысли у меня следующие :

  1. Если на вход подаётся список с числами и (len!=1) — сортировать список tmp.sort(key=key) return tmp[0] код

выбрать первый элемент(мин) или последний(макс)

Если на вход подаётся текст(получается что len==1) — реализую поиск меньшей/большей буквы

Но если мне на вход подается кортеж —

[[1,2], [3, 4], [9, 0]], key=lambda x: x[1]

то при проверке на длинну, он попадает под len == 1, и не проходит реализацию.

Подскажите, видимо я пытаюсь построить велосипед, как будет правильнее реализовать такую функцию?

2 ответа 2

Если вы хотите повторить реализацию стандартной функции max (или min , но там почти так же, поэтому я расскажу про один max ), то вот несколько соображений, которые нужны для этого:

Если аргумент один, то считаем его объектом, по которому можно пройтись циклом (iterable). Такими объектами являются списки, кортежи, строки, генераторы и многое другое, так что не надо рассматривать списки отдельно от строк.

Если аргументов два или больше, то соединяем их в один список, который автоматически iterable.

Переменное число аргументов можно принять с помощью *args .

С учётом всего этого можно написать функцию примерно такую:

Насколько я могу судить, она (в рамках заданной мной области применимости) соответствует стандартной реализации max в Python:

(Но в этой функции я для простоты опустил обработку пустых списков и поддержку объектов, в которым нельзя обращаться по индексу (генераторы, например), так что данная функция годится только в образовательных целях, а в реальных программах используйте обычный max 🙂

Вот более точная реализация (теперь уже не max , а min ), но более сложная для понимания, поэтому пишу её отдельно. Чтобы поддерживать обработку iterable-объектов, придётся отказаться от обращения к нему по индексу и устанавливать первый элемент более хитро.

Такая функция соответствует родной реализации почти во всех известных мне случаях (кроме одного несущественного для вопроса min([]) ):

Здесь, в отличие от более простой предыдущей реализации, теперь не создаётся никаких списков, а есть лишь несколько переменных, поэтому эта реализация O(1) в памяти (можно без траты оперативы обработать сколь угодно много элементов, если достать соответствующий генератор, например range ( xrange в Python 2)). Цикл тут один-единственный, поэтому O(n) по шагам, что соответствует стандартной реализации (если верить комментарию jfs).

Оцените статью
Много толка
Добавить комментарий