Подтвердить что ты не робот

Как работает функция min/max в вложенном списке?

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

my_list = [[1, 2, 21], [1, 3], [1, 2]]

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

min(my_list)

Полученный результат

[1, 2]

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

4b9b3361

Ответ 1

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

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

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


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

На странице Википедии лексикографическая сортировка

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

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

>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list)
[1, 2]

Что происходит в этом случае 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

>>> sorted(my_list)
[[1, 2], [1, 2, 21], [1, 3]]

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

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

>>> my_list=[[1,2],[1,2]]
>>> min(my_list)
[1, 2]

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

>>> my_list=[[1,2],[1,2]]
>>> [id(i) for i in my_list]
[140297364849368, 140297364850160]
>>> id(min(my_list))
140297364849368

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

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

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

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

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

>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list,key=len)            # Notice the key argument
[1, 3]

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


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

До Python2

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

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

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

>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
1

Python3 и далее

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

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

>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < list()

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

>>> my_list=[1,2.0]
>>> min(my_list)
1

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

Ответ 2

Один простой пример использования для лексикографической сортировки заключается в создании класса namedtuple.

from collections import namedtuple
Time = namedtuple('Time', ['hours', 'minutes', 'seconds'])

t1 = Time(hours=8, minutes=15, seconds=30)
t2 = Time(hours=8, minutes=15, seconds=0)
t3 = Time(hours=8, minutes=30, seconds=30)
t4 = Time(hours=7, minutes=15, seconds=30)

assert min(t1, t2, t3, t4) == t4
assert max(t1, t2, t3, t4) == t3

Ответ 3

Два списка сравниваются по элементам

Даже если размеры двух списков различны, два списка сравниваются по элементам, начиная с сравнения с первым элементом.

Теперь предположим, что каждый элемент списка проверен, и они одинаковы, и в сокращенном списке нет следующего элемента. Тогда более короткий список объявляется меньшим, чем более длинный.

Примеры:

>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>> [1,3]<[1,2,21]
False
>>>[1,2,22]<[1,2,21]
False
>>>[1]<[1,2,21]
True
>>>

Ответ 4

он сравнивает списки elementwise:

>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>>