fonction python max utilisant 'key' et expression lambda

189

Je viens de fond OOP et j'essaye d'apprendre le python. J'utilise la maxfonction qui utilise une expression lambda pour renvoyer l'instance de type Playerayant le maximum totalScoredans la liste players.

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

La fonction renvoie correctement une instance de type Playerayant un maximum totalScore. Je ne comprends pas les trois choses suivantes:

  1. Comment fonctionne la maxfonction? Quels sont les arguments qu'il prend? J'ai regardé la documentation mais je n'ai pas compris.
  2. À quoi sert le mot-clé keydans la fonction max? Je sais qu'il est également utilisé dans le contexte de la sortfonction
  3. Signification de l'expression lambda? Comment les lire? Comment travaillent-ils?

Ce sont toutes des questions conceptuelles très noobish mais qui m'aideront à comprendre la langue. Il serait utile que vous donniez des exemples à expliquer. Merci

Vijay
la source
Quelle version de Python?
charmlessCoin
3
Avez-vous consulté la documentation ?
Inbar Rose
@charmlessCoin python 2.7.5
Vijay
2
@InbarRose J'ai vérifié la documentation pour la fonction max. Je n'ai pas vraiment compris.
Vijay
11
@InbarRose Cette page est en fait maintenant le meilleur résultat sur Google pour python max lambdaet peut-être peut-être en fait plus utile pour les nouveaux utilisateurs.
Mark le

Réponses:

296

lambda est une fonction anonyme, elle équivaut à:

def func(p):
   return p.totalScore     

Devient maintenant max:

max(players, key=func)

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

Notez que cela lambdaéquivaut à ce que vous mettriez dans une instruction return d'un def. Ainsi, vous ne pouvez pas utiliser d'instructions dans un lambda, seules les expressions sont autorisées.


Que fait max-on?

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

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

Ainsi, il renvoie simplement l'objet qui est le plus grand.


Comment ça keymarche?

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

Pour modifier l'objet avant la comparaison, ou pour comparer en fonction d'un attribut / index particulier, vous devez utiliser l' keyargument.

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 maxcompare les éléments en utilisant leurs valeurs d'origine (les chaînes sont comparées lexicographiquement afin que vous les obteniez '2'en sortie):

>>> max(lis)
'2'

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

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

Exemple 2: application maxà une liste de tuples.

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

Par défaut max, comparera les éléments par le premier index. Si le premier index est le même, il comparera le deuxième index. Comme dans mon exemple, tous les éléments ont un premier index unique, vous obtiendrez donc ceci comme réponse:

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

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

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

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

Liste avec des éléments mixtes:

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 faire cela :

>>> 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'
Ashwini Chaudhary
la source
Je pense que c'est vieux, mais j'avais une question à ce sujet. Je vois pour la fonction lambda, la variable x ou i ou autre chose représente toujours la valeur à cet index dans la liste. Cette itération est-elle effectuée par la fonction max ou par le lambda? Les fonctions lambda itèrent-elles toujours sur les valeurs possibles? Par exemple: lengths = map(lambda word: len(word), words)words=['It', 'is', 'raining', 'cats', 'and', 'dogs']je vois que le lambda itère sur chaque mot de la liste. Fait-il toujours cela?
Mo2
1
@ Mo2 L'itération est effectuée par maxnot lambda( keyarg est facultatif), et pendant l'itération, chaque élément est passé à la fonction spécifiée dans keyet la valeur renvoyée est ensuite utilisée pour la comparaison.
Ashwini Chaudhary
2
Juste pour les gens qui sont venus ici en recherchant sur Google "paramètre clé max". max(lis, key=lambda x:int(x))peut être simplifié comme max(lis, key=int). Python a une fonction intégrée, int (). De même, vous pouvez utiliser toute autre fonction intégrée comme keyargument. Par exemple, vous pouvez obtenir la plus longue chaîne de lis=['a', 'aa', 'aaa']parmax(lis, key=len)
YOUNG
1
@YOUNG Nous pouvons utiliser une fonction comme argument clé non seulement des fonctions builtin, la seule condition est que la fonction doit accepter les articles qui lui sont transmises par max, min, sortedetc correctement. De plus, je l'ai mentionné max(lis, key=int)à la fin. :-)
Ashwini Chaudhary
@Ashwini Chaudhary .. supposons que si j'ai une liste comme [1,2,3,4,5]. ici tous les éléments sont différents. J'utilise la fonction donnée max (set (mylist), key = mylist.count) pour trouver les éléments les plus fréquents. car dans ce cas il n'y a aucun élément qui se répète. il renvoie l'article le plus bas. Pouvons-nous faire quelque chose pour qu'il renvoie zéro ou nul dans ce cas.
vikrant rana
14

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

Concernant lambda:

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

>>> times_two = lambda x: 2*x
>>> times_two(2)
4
Markus Unterwaditzer
la source
10

Comment fonctionne la fonction max?

Il recherche l'élément "le plus grand" dans un itérable. Je suppose que vous pouvez rechercher ce que c'est, mais sinon, c'est quelque chose sur lequel vous pouvez faire une boucle, c'est-à-dire une liste ou une chaîne.

À quoi sert la clé de mot-clé dans la fonction max? Je sais qu'il est également utilisé dans le contexte de la fonction de tri

Keyest une fonction lambda qui dira maxquels objets de l'itérable sont plus grands 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 en quelque sorte une question plus vaste. En termes simples, un lambda est une fonction que vous pouvez transmettre et que d'autres morceaux de code utilisent. Prenons ceci par exemple:

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

Cela prend deux objets, aet bet une fonction f. Il appelle f()chaque objet, puis les ajoute ensemble. Alors regardez cet appel:

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

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

En termes pas si simples, les lambdas proviennent du calcul lambda, 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 fait comprendre qu'il ici .

Il est probablement préférable de lire un peu plus à ce sujet, car les lambdas peuvent être déroutants et il n'est pas immédiatement évident à quel point ils sont utiles. Vérifiez ici .

sans charme
la source
8

maxest utilisée pour obtenir le maximum d'un fichier iterable.

Les itérateurs peuvent être des listes, des tuples, 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.

Donc, key=funcfondamentalement , le nous permet de passer un argument optionnel keyà la fonction sur la base de laquelle l'itérateur donné / les arguments sont triés et le maximum est retourné.

lambdaest un mot-clé python qui agit comme une pseudo fonction. Ainsi, lorsque vous lui passez l' playerobjet, il reviendra player.totalScore. Ainsi, l'itérable passé à function triera enmax fonction du key totalScore des playerobjets qui lui sont donnés & retournera celui playerqui a le maximum totalScore.

Si aucun keyargument n'est fourni, le maximum est renvoyé selon les ordres 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')
shad0w_wa1k3r
la source
6

Selon la documentation :

max (iterable [, key])
max (arg1, arg2, * args [, key])
Renvoie le plus grand élément d'un itérable ou le plus grand de deux ou plusieurs arguments.

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

L'argument clé facultatif spécifie une fonction de classement à un argument comme 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)).

Ce que cela signifie, c'est que dans votre cas, vous fournissez une liste, dans ce cas players . Ensuite, la maxfonction parcourra 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 la playerdétermination de sa valeur à des fins de comparaison est délicat, on vous donne donc l' keyargument pour déterminer comment la maxfonction décidera de la valeur de chacun player. Dans ce cas, vous utilisez une fonction lambda pour dire "pour chacun pdans playersget p.totalscoreet utilisez-le comme valeur de comparaison".

Rose Inbar
la source
4

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

L'argument mot-clé keya sa valeur par défaut Nonemais il accepte la fonction à évaluer, considérez-le comme un wrapper qui évalue l'itération en fonction de la fonction

Considérez 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 à key), il renvoie la valeur maximale de la clé (par ordre alphabétique)

Ex. Au lieu de trouver la valeur maximale de la clé par ordre alphabétique, vous devrez peut-être trouver la clé maximale par longueur de 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 par conséquent tout en évaluant les valeurs au lieu de considérer par ordre alphabétique, elle gardera une trace de la longueur maximale de la clé et retournera la clé qui a 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 qui a la valeur maximale

Gahan
la source