функція python max, використовуючи вираз 'key' та лямбда


181

Я родом з фону OOP і намагаюся вивчити пітон. Я використовую 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
Ви проконсультувались з документацією ?
Inbar Rose

@charmlessCoin python 2.7.5
Vijay

2
@InbarRose Я перевірив документацію на функцію max. Не дуже зрозумів.
Vijay

10
@InbarRose Ця сторінка справді є найвищим результатом в Google python max lambdaі, можливо, може бути кориснішою для нових користувачів.
Марк

Відповіді:


278

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']я бачу, що лямбда повторюється над кожним словом у списку. Чи завжди це робить?
Mo2

1
@ Mo2 Ітерація виконується maxне lambda( keyаргумент необов’язковий), і під час ітерації кожен елемент передається функції, зазначеній у, 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)наприкінці. :-)
Ashwini Chaudhary

@Ashwini Chaudhary .. припустимо, якщо у мене є такий список, як [1,2,3,4,5]. тут усі предмети різні. Я використовую задану функцію max (set (мій список), key = mylist.count), щоб знайти найчастіші предмети. оскільки в цьому випадку немає елемента, який би повторювався. це повернення найнижчого предмета. Чи можемо ми щось зробити так, щоб він повертав нуль або нуль у такому випадку.
vikrant rana

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, і додає два разом.

Не так простими словами, лямбда походять від обчислення лямбда, що є ідеєю функції, яка повертає функцію; дуже класна математична концепція для вираження обчислень. Ви можете прочитати про це тут , а потім насправді зрозуміти це тут .

Напевно, краще почитати про це трохи більше, оскільки лямбдаси можуть збивати з пантелику, і не відразу очевидно, наскільки вони корисні. Перевірте тут .


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 загального результату 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 (ітерабельний [, ключ])
max (arg1, arg2, * args [, key])
Повернення найбільшого елемента в ітерабельному або найбільшому з двох або більше аргументів.

Якщо надано один позиційний аргумент, його можна перетворити на незаповнений ітерабел (наприклад, не порожній рядок, кортеж чи список). Повертається найбільший елемент в ітерабелі. Якщо надано два або більше позиційних аргументів, повертається найбільший з позиційних аргументів.

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

Це говорить про те, що у вашому випадку ви надаєте перелік у цьому випадку players. Тоді maxфункція повторить усі елементи списку та порівняє їх між собою, щоб отримати "максимум".

Як ви можете собі уявити, складний об'єкт на кшталт playerвизначення його значення для порівняння є складним, тому вам надають keyаргумент, щоб визначити, як maxфункція буде визначати значення кожного player. У цьому випадку ви використовуєте лямбда-функцію, щоб сказати "для кожного pв playersотриманні p.totalscoreі використовувати це як його значення для порівняння".


3

max будується функція, яка бере перший аргумент 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), він повертає максимальне значення ключа (в алфавітному порядку)

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

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

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

Вих.

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

у цьому прикладі функція лямбда повертає значення відповідного словника, яке має максимальне значення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.