web-dev-qa-db-fra.com

python fonction max utilisant 'key' et l'expression lambda

Je viens de OOP et j'essaie d'apprendre le python. J'utilise la fonction max qui utilise une expression lambda pour renvoyer l'instance de type Player ayant un maximum de totalScore dans la liste players.

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

La fonction renvoie correctement une instance de type Player ayant un maximum de totalScore. Je suis confus sur les trois choses suivantes:

  1. Comment fonctionne la fonction max? Quels sont les arguments qu'il prend? J'ai regardé la documentation mais je n'ai pas compris.
  2. Quelle est l'utilisation du mot clé key in max? Je sais qu'il est également utilisé dans le contexte de la fonction sort
  3. Signification de l'expression lambda? Comment les lire? Comment travaillent-ils?

Ce sont toutes des questions conceptuelles très nobles mais qui m'aideront à comprendre le langage. Cela vous aiderait si vous pouviez donner des exemples à expliquer. Merci

149
Vijay

lambda est une fonction anonyme, elle est équivalente à:

def func(p):
   return p.totalScore     

Maintenant, max devient:

max(players, key=func)

Mais comme les instructions def sont des instructions composées, elles ne peuvent pas être utilisées lorsqu'une expression est requise, c'est pourquoi parfois les instructions lambda sont utilisées.

Notez que lambda est équivalent à ce que vous auriez mis dans une instruction return de def. Ainsi, vous ne pouvez pas utiliser d'instructions dans un lambda, seules les expressions sont autorisées.


Que fait max?

max (a, b, c, ... [ clé = func]) -> valeur

Avec un seul argument itérable, renvoyez son plus grand élément. Avec deux arguments ou plus, retourne le plus grand argument.

Donc, il retourne simplement l'objet qui est le plus grand.


Comment fonctionne key?

Par défaut, dans Python 2 key compare les éléments en fonction d'un ensemble de règles en fonction du type des objets (par exemple, une chaîne est toujours supérieure à un entier). .

Pour modifier l'objet avant la comparaison ou pour effectuer une comparaison basée sur un attribut/index particulier, vous devez utiliser l'argument key.

Exemple 1:

Un exemple simple, supposons que vous ayez une liste de nombres sous forme de chaîne, mais que vous souhaitiez comparer ces éléments par leur valeur entière.

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

Ici, max compare les éléments en utilisant leurs valeurs d'origine (les chaînes sont comparées lexicographiquement afin que vous obteniez '2' en sortie):

>>> max(lis)
'2'

Pour comparer les éléments par leur valeur entière, utilisez key avec un simple lambda:

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

Exemple 2: Application de max à une liste de n-uplets.

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

Par défaut, max comparera les éléments en fonction du premier index. Si le premier index est identique, le second index sera comparé. Comme dans mon exemple, tous les éléments ont un premier index unique, vous obtiendrez donc la réponse suivante:

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

Mais que se passe-t-il si vous voulez comparer chaque élément avec la valeur à l'indice 1? Simple: utilisez lambda:

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

Comparaison d'éléments dans une itérable contenant des objets de type différent :

Liste avec articles mélangés:

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

Dans Python 2, il est possible de comparer des éléments de deux types différents :

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

Mais dans Python 3 vous ne pouvez plus le faire :

>>> 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()

Mais cela fonctionne, car nous comparons la version entière de chaque objet:

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

Comment fonctionne la fonction max?

Il cherche le "plus grand" élément dans un itérable. Je suppose que vous pouvez rechercher ce que c'est, mais si ce n'est pas le cas, vous pouvez en faire une boucle, c'est-à-dire une liste ou une chaîne.

Quelle est l'utilisation de la clé de mot-clé dans la fonction max? Je sais qu'il est également utilisé dans le contexte de la fonction de tri

Key est une fonction lambda qui indique à max quels objets de l'itérable sont plus gros que les autres. Dites si vous triez un objet que vous avez créé vous-même, et non quelque chose d'évident, comme des entiers.

Signification de l'expression lambda? Comment les lire? Comment travaillent-ils?

C'est une sorte de plus grande question. En termes simples, un lambda est une fonction que vous pouvez faire passer et que d’autres morceaux de code l’utilisent. Prenons ceci par exemple:

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

Cela prend deux objets, a et b, et une fonction f. Il appelle f() sur chaque objet, puis les additionne. Alors regardez cet appel:

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

sum() prend 2 et appelle l'expression lambda dessus. Donc, f(a) devient 2 * 2, qui devient 4. Il le fait ensuite pour b, et ajoute les deux ensemble.

En termes pas si simples, les lambdas proviennent du lambda calcul, qui est l’idée d’une fonction qui renvoie une fonction; un concept mathématique très cool pour exprimer le calcul. Vous pouvez lire à ce sujet ici , et ensuite réellement comprendre il ici .

Il est probablement préférable de lire un peu plus à ce sujet, car les lambdas peuvent être déroutants, et leur utilité n’est pas immédiatement évidente. Vérifiez ici .

9
charmlessCoin

Version fortement simplifiée de max:

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

En ce qui concerne le lambda:

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

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

La fonction max est utilisée pour tirer le maximum d'un iterable.

Les itérateurs peuvent être des listes, des n-uplets, des objets dict, etc. ou même des objets personnalisés, comme dans l'exemple que vous avez fourni.

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.

Ainsi, le key=func nous permet fondamentalement de passer un argument optionnel key à la fonction sur la base de laquelle les itérateurs/arguments donnés sont triés et le maximum est renvoyé.

lambda est un mot clé python qui agit comme une pseudo-fonction. Ainsi, lorsque vous passez l'objet player, il retournera player.totalScore. Ainsi, l'itérable passé à la fonction max triera en fonction de la keytotalScore des objets player qui lui ont été donnés et retournera la player qui a le maximum totalScore.

Si aucun argument key n'est fourni, le maximum est renvoyé conformément aux commandes Python par défaut.

Exemples -

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')
5
shad0w_wa1k3r

Selon le documentation :

max (itérable [ clé])
max (arg1, arg2, * args [ clé])
Renvoie le plus grand élément dans un itérable ou le plus grand de deux arguments ou plus.

Si un argument de position est fourni, iterable doit être un iterable non vide (tel qu'une chaîne, un tuple ou une liste non vide). Le plus gros élément de l'itérable est renvoyé. Si deux arguments de position ou plus sont fournis, le plus grand des arguments de position est renvoyé.

L'argument optionnel key spécifie une fonction de classement à un argument similaire à celle utilisée pour list.sort (). L'argument clé, s'il est fourni, doit être sous forme de mot clé (par exemple, max (a, b, c, clé = func)).

Cela signifie que, dans votre cas, vous fournissez une liste, dans ce cas players. Ensuite, la fonction max effectuera une itération sur tous les éléments de la liste et les comparera les uns aux autres pour obtenir un "maximum".

Comme vous pouvez l’imaginer, avec un objet complexe tel que player, il est difficile de déterminer sa valeur à des fins de comparaison. Vous obtenez donc l’argument key pour déterminer comment la fonction max déterminera la valeur de chaque player. Dans ce cas, vous utilisez une fonction lambda pour dire "pour chaque p dans players obtenir p.totalscore et l'utiliser comme valeur de comparaison".

5
Inbar Rose

max est une fonction intégrée qui prend comme premier argument un iterable (comme une liste ou un tuple)

le mot clé argument key a la valeur par défaut None mais accepte les fonctions à évaluer, considère-le comme un wrapper évaluant itérable en fonction de la fonction.

Considérons cet exemple de dictionnaire:

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

Ex:

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

Comme vous pouvez le voir, si vous ne passez que l'itérable sans kwarg (une fonction sur key), la valeur maximale de key est renvoyée (par ordre alphabétique).

Ex. Au lieu de rechercher alphabétiquement la valeur maximale de la clé, vous devrez peut-être rechercher la clé maximale en fonction de la longueur de la clé:

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

dans cet exemple, la fonction lambda renvoie la longueur de la clé qui sera itérée. Ainsi, tout en évaluant les valeurs au lieu de tenir compte alphabétiquement, il gardera la trace de la longueur maximale de la clé et retournera la clé qui aura la longueur maximale.

Ex.

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

dans cet exemple, la fonction lambda renvoie la valeur de la clé de dictionnaire correspondante ayant la valeur maximale

1
Gahan