Функция Python Max с использованием «ключа» и лямбда-выражения

182

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

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

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

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

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

Виджай
источник
Какая версия Python?
charmlessCoin
2
Вы ознакомились с документацией ?
Инбар Роуз
@charmlessCoin python 2.7.5
Виджей
2
@InbarRose Я проверил документацию на максимальную функцию. Не очень понял это.
Виджай
10
@InbarRose Эта страница на самом деле является лучшим результатом для Google python max lambdaи, возможно, может быть более полезной для новых пользователей.
Марк

Ответы:

279

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

def func(p):
   return p.totalScore     

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

max(players, key=func)

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

Обратите внимание, что lambdaэто эквивалентно тому, что вы бы указали в операторе возврата 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'
Ашвини Чаудхари
источник
Я думаю, что это старый, но у меня был вопрос по этому поводу. Я вижу для лямбда-функции, переменная x или i или что-либо еще всегда представляет значение по этому индексу в списке. Эта итерация выполняется функцией max или лямбдой? Всегда ли лямбда-функции перебирают возможные значения? Например: lengths = map(lambda word: len(word), words)где words=['It', 'is', 'raining', 'cats', 'and', 'dogs']я вижу, что лямбда выполняет итерацию по каждому слову в списке. Всегда ли это так?
Мо2
1
@ Mo2 Итерация выполняется с помощью maxnot lambda( keyarg является необязательным), и во время итерации каждый элемент передается в функцию, указанную в, keyи возвращаемое значение затем используется для сравнения.
Ашвини Чаудхари
2
Просто для людей, которые пришли сюда, прибегая к помощи «параметра max key». max(lis, key=lambda x:int(x))можно упростить как max(lis, key=int). Python имеет встроенную функцию int (). Точно так же вы можете использовать любые другие встроенные функции в качестве keyаргумента. Например , вы можете получить самую длинную строку из lis=['a', 'aa', 'aaa']поmax(lis, key=len)
YOUNG
1
@YOUNG Мы можем использовать любую функцию в качестве ключевого аргумента, а не только встроенные функции, единственное условие - функция должна принимать элементы, переданные ей max, minи sortedт. Д. Должным образом. Плюс я упомянул max(lis, key=int)прямо в конце. :-)
Ашвини Чаудхари
@ Ашвини Чаудхари ... предположим, если у меня есть список вроде [1,2,3,4,5]. здесь все предметы разные. Я использую данную функцию max (set (mylist), key = mylist.count), чтобы найти наиболее часто встречающиеся элементы. так как в этом случае нет элемента, который повторяется. это возвращает самый низкий пункт. Можем ли мы сделать что-то, чтобы в таком случае он возвращал ноль или ноль?
Викрант Рана
12

Сильно упрощенная версия 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
Маркус Унтервадитцер
источник
10

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

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

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

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

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

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

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и складывает их вместе.

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

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

charmlessCoin
источник
7

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')
shad0w_wa1k3r
источник
6

Согласно документации :

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

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

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

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

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

Инбар Роуз
источник
3

maxвстроена функция, которая принимает первый аргумент an 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'

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

Ex.

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

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

Gahan
источник