Функция python max с использованием "ключа" и выражения лямбда

Я пришел из фона ООП и пытался узнать python. Я использую функцию max, которая использует выражение лямбда, чтобы вернуть экземпляр типа Player, имеющий максимум totalScore среди списка players.

def winner():
    w = max(players, key=lambda p: p.totalScore)

Функция корректно возвращает экземпляр типа Player с максимальным значением totalScore. Я запутался в следующих трех вещах:

  • Как работает функция max? Какие аргументы он принимает? Я посмотрел документацию, но не понял.
  • Что такое ключевое слово key в функции max? Я знаю, что он также используется в контексте функции sort
  • Значение выражения лямбда? Как их читать? Как они работают?

Все это очень ноубийские концептуальные вопросы, но поможет мне понять язык. Это поможет, если вы сможете привести примеры для объяснения. Благодаря

Ответ 1

lambda - это анонимная функция, она эквивалентна:

def func(p):
   return p.totalScore     

Теперь max становится:

max(players, key=func)

Но поскольку операторы def являются составными, их нельзя использовать там, где требуется выражение, поэтому иногда используются lambda выражения.

Обратите внимание, что lambda эквивалентна тому, что вы бы указали в операторе return для def. Таким образом, вы не можете использовать операторы внутри lambda, разрешены только выражения.


Что делает max?

max (a, b, c,... [, key = func]) → значение

С одним итеративным аргументом верните его самый большой элемент. С двумя или более аргументами верните самый большой аргумент.

Таким образом, он просто возвращает объект, который является самым большим.


Как работает key?

По умолчанию в Python 2 key сравнивает элементы на основе набора правил, основанных на типе объектов (например, строка всегда больше целого числа).

Чтобы изменить объект перед сравнением или сравнить по определенному атрибуту/индексу, вы должны использовать key аргумент.

Пример 1:

Простой пример. Предположим, у вас есть список чисел в строковой форме, но вы хотите сравнить эти элементы по их целочисленным значениям.

>>> lis = ['1', '100', '111', '2']

Здесь max сравнивает элементы, используя их исходные значения (строки сравниваются лексикографически, поэтому в качестве результата вы получите '2'):

>>> max(lis)
'2'

Для сравнения элементов по их целочисленному значению используйте key с простой lambda выражением:

>>> max(lis, key=lambda x:int(x))  # compare 'int' version of each item
'111'

Пример 2: применение max к списку кортежей.

>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]

По умолчанию max сравнивает элементы по первому индексу. Если первый индекс совпадает, тогда он будет сравнивать второй индекс. Как и в моем примере, все элементы имеют уникальный первый индекс, поэтому вы получите ответ:

>>> max(lis)
(4, 'e')

Но что, если вы хотите сравнить каждый элемент по значению с индексом 1? Просто: используйте lambda:

>>> max(lis, key = lambda x: x[1])
(-1, 'z')

Сравнение элементов в итерируемом объекте, который содержит объекты различного типа:

Список со смешанными предметами:

lis = ['1','100','111','2', 2, 2.57]

В Python 2 можно сравнивать элементы двух разных типов:

>>> max(lis)  # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x))  # compare integer version of each item
'111'

Но в Python 3 вы больше не можете этого делать:

>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
  File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
    max(lis)
TypeError: unorderable types: int() > str()

Но это работает, так как мы сравниваем целочисленную версию каждого объекта:

>>> max(lis, key=lambda x: int(x))  # or simply 'max(lis, key=int)'
'111'

Ответ 2

Сильно упрощенная версия max:

def max(items, key=lambda x: x):
    current = item[0]
    for item in items:
        if key(item) > key(current):
            current = item
    return current

Относительно лямбда:

>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5

>>> times_two = lambda x: 2*x
>>> times_two(2)
4

Ответ 3

Как работает функция max?

Он ищет "самый большой" элемент в истребителе. Я буду считать, что вы может посмотреть, что это такое, но если нет, это то, что вы можете перебрать, то есть список или строку.

Что такое ключ ключевого слова в функции max? Я знаю, что он также используется в контексте функции сортировки

Key - это лямбда-функция, которая сообщает max, что объекты в iterable больше других. Скажем, если бы вы сортировали какой-то объект, который вы создали сами, а не что-то очевидное, например целые числа.

Значение лямбда-выражения? Как их читать? Как они работают?

Такой вопрос больше. Проще говоря, лямбда - это функция, которую вы можете пройти, и использовать ее в других частях кода. Возьмите это, например:

def sum(a, b, f):
    return (f(a) + f(b))

Это принимает два объекта: a и b и функцию f. Он вызывает f() для каждого объекта, а затем добавляет их вместе. Итак, посмотрите на этот вызов:

>>> sum(2, 2, lambda a:  a * 2)
8

sum() принимает 2 и вызывает на нем лямбда-выражение. Итак, f(a) становится 2 * 2, который становится 4. Затем он делает это для b и добавляет их вместе.

В не столь простых терминах лямбды исходят из лямбда-исчисления, что является идеей функции, возвращающей функцию; очень крутая математическая концепция для выражения вычислений. Вы можете прочитать об этом здесь, а затем на самом деле понять его здесь.

Вероятно, лучше прочитать об этом немного больше, поскольку лямбды могут сбивать с толку, и не сразу видно, насколько они полезны. Проверьте здесь.

Ответ 4

В соответствии с документацией:

max (iterable [, key])
max (arg1, arg2, * args [, key])
Возврат самый большой элемент в итерабельном или самом большом из двух или более аргументов.

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

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

Это говорит о том, что в вашем случае вы предоставляете список, в данном случае players. Затем функция max будет перебирать все элементы в списке и сравнивать их друг с другом, чтобы получить "максимум".

Как вы можете себе представить, сложный объект, такой как player, определяющий его значение для сравнения, является сложным, поэтому вам предоставляется аргумент key, чтобы определить, как функция max будет определять значение каждого player. В этом случае вы используете функцию лямбда, чтобы сказать "для каждого p в players получить p.totalscore и использовать это как его значение для сравнения".

Ответ 5

Функция

max используется для получения максимума из iterable.

Итераторами могут быть списки, кортежи, объекты dict и т.д. Или даже настраиваемые объекты, как в примере, который вы указали.

max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.

Итак, key=func в основном позволяет нам передать необязательный аргумент key функции, на основе которой отсортированные данные итератора/аргументы сортируются и возвращается максимум.

lambda - ключевое слово python, которое действует как псевдофункция. Итак, когда вы передаете ему объект player, он вернет player.totalScore. Таким образом, итерабельность, передаваемая функции max, будет сортироваться в соответствии с key totalScore объектов player, предоставленных ей, и вернет player, у которого максимум totalScore.

Если аргумент key не указан, максимальный возвращается в соответствии с порядками Python по умолчанию.

Примеры -

max(1, 3, 5, 7)
>>>7
max([1, 3, 5, 7])
>>>7

people = [('Barack', 'Obama'), ('Oprah', 'Winfrey'), ('Mahatma', 'Gandhi')]
max(people, key=lambda x: x[1])
>>>('Oprah', 'Winfrey')

Ответ 6

max встроена функция, которая принимает первый аргумент a iterable (например, список или кортеж)

ключевой аргумент key имеет значение по умолчанию None, но он принимает функцию для оценки, рассматривает ее как оболочку, которая оценивает итерацию на основе функции

Рассмотрим этот пример словаря:

d = {'aim':99, 'aid': 45, 'axe': 59, 'big': 9, 'short': 995, 'sin':12, 'sword':1, 'friend':1000, 'artwork':23}

Пример:

>>> max(d.keys())
'sword'

Как вы можете видеть, если вы передаете только итерацию без kwarg (функция key), она возвращает максимальное значение ключа (в алфавитном порядке)

Ex. Вместо того, чтобы находить максимальное значение ключа в алфавитном порядке, вам может потребоваться найти максимальный ключ по длине ключа:

>>>max(d.keys(), key=lambda x: len(x))
'artwork'

в этом примере лямбда-функция возвращает длину ключа, которая будет итерации, поэтому при оценке значений вместо рассмотрения в алфавитном порядке она будет отслеживать максимальную длину ключа и возвращает ключ с максимальной длиной

Исх.

>>> max(d.keys(), key=lambda x: d[x])
'friend'

в этом примере лямбда-функция возвращает значение соответствующего словарного ключа с максимальным значением