Python Max-Funktion mit 'Schlüssel' und Lambda-Ausdruck

180

Ich komme aus dem OOP-Hintergrund und versuche, Python zu lernen. Ich verwende die maxFunktion, die einen Lambda-Ausdruck verwendet, um die Instanz des Typs Playermit dem Maximum totalScorein der Liste zurückzugeben players.

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

Die Funktion gibt eine Instanz des Typs Playermit Maximum korrekt zurück totalScore. Ich bin verwirrt über die folgenden drei Dinge:

  1. Wie funktioniert die maxFunktion? Was sind die Argumente dafür? Ich sah mir die Dokumentation an, verstand sie aber nicht.
  2. Was ist die Verwendung des Schlüsselworts keyin der Max-Funktion? Ich weiß, dass es auch im Kontext der sortFunktion verwendet wird
  3. Bedeutung des Lambda-Ausdrucks? Wie lese ich sie? Wie arbeiten Sie?

Dies sind alles sehr noobische konzeptionelle Fragen, die mir jedoch helfen werden, die Sprache zu verstehen. Es wäre hilfreich, wenn Sie Beispiele zur Erklärung geben könnten. Vielen Dank

Vijay
quelle
Welche Python-Version?
charmlessCoin
2
Haben Sie die Dokumentation konsultiert ?
Inbar Rose
@charmlessCoin Python 2.7.5
Vijay
2
@InbarRose Ich habe die Dokumentation auf maximale Funktion überprüft. Ich habe es nicht wirklich verstanden.
Vijay
10
@InbarRose Diese Seite ist jetzt das Top-Ergebnis bei Google python max lambdaund möglicherweise für neue Nutzer hilfreicher.
Mark

Antworten:

274

lambda ist eine anonyme Funktion und entspricht:

def func(p):
   return p.totalScore     

Jetzt maxwird:

max(players, key=func)

Da defAnweisungen zusammengesetzte Anweisungen sind, können sie nicht verwendet werden, wenn ein Ausdruck erforderlich ist. Deshalb werden manchmal auch Anweisungen lambdaverwendet.

Beachten Sie, dass dies dem lambdaentspricht, was Sie in eine return-Anweisung von a eingefügt haben def. Daher können Sie keine Anweisungen in a verwenden lambda, nur Ausdrücke sind zulässig.


Was macht maxdas

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

Geben Sie mit einem einzigen iterierbaren Argument das größte Element zurück. Geben Sie mit zwei oder mehr Argumenten das größte Argument zurück.

Es wird also einfach das größte Objekt zurückgegeben.


Wie funktioniert das key?

Standardmäßig keyvergleicht Python 2 Elemente basierend auf einer Reihe von Regeln, die auf dem Typ der Objekte basieren (z. B. ist eine Zeichenfolge immer größer als eine Ganzzahl).

Um das Objekt vor dem Vergleich zu ändern oder anhand eines bestimmten Attributs / Index zu vergleichen, müssen Sie das keyArgument verwenden.

Beispiel 1:

Angenommen, Sie haben eine Liste von Zahlen in Zeichenfolgenform, möchten diese Elemente jedoch anhand ihres ganzzahligen Werts vergleichen.

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

Hier werden maxdie Elemente anhand ihrer ursprünglichen Werte verglichen (Zeichenfolgen werden lexikografisch verglichen, sodass Sie sie '2'als Ausgabe erhalten):

>>> max(lis)
'2'

Um die Elemente anhand ihres ganzzahligen Werts zu vergleichen, verwenden Sie keyFolgendes lambda:

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

Beispiel 2: Anwenden maxauf eine Liste von Tupeln.

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

Standardmäßig maxwerden die Elemente anhand des ersten Index verglichen. Wenn der erste Index identisch ist, wird der zweite Index verglichen. Wie in meinem Beispiel haben alle Elemente einen eindeutigen ersten Index, sodass Sie diesen als Antwort erhalten:

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

Was aber, wenn Sie jedes Element anhand des Werts bei Index 1 vergleichen möchten? Einfach: verwenden lambda:

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

Vergleichen von Elementen in einer Iterable, die Objekte unterschiedlichen Typs enthält :

Liste mit gemischten Elementen:

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

In Python 2 können Elemente zweier verschiedener Typen verglichen werden :

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

Aber in Python 3 können Sie das nicht mehr tun :

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

Dies funktioniert jedoch, da wir die Ganzzahlversion jedes Objekts vergleichen:

>>> max(lis, key=lambda x: int(x))  # or simply `max(lis, key=int)`
'111'
Ashwini Chaudhary
quelle
Ich denke, das ist alt, aber ich hatte eine Frage dazu. Ich sehe für die Lambda-Funktion, dass die Variable x oder i oder irgendetwas anderes immer den Wert an diesem Index in der Liste darstellt. Wird diese Iteration von der Max-Funktion oder vom Lambda durchgeführt? Iterieren Lambda-Funktionen immer über die möglichen Werte? Zum Beispiel: lengths = map(lambda word: len(word), words)wo words=['It', 'is', 'raining', 'cats', 'and', 'dogs']ich sehe, dass das Lambda über jedes Wort in der Liste iteriert. Tut es das immer?
Mo2
1
@ Mo2 Die Iteration erfolgt mit maxnot lambda( keyarg ist optional), und während der Iteration wird jedes Element an die in angegebene Funktion übergeben, keyund der zurückgegebene Wert wird dann zum Vergleich verwendet.
Ashwini Chaudhary
2
Nur für die Leute, die hierher kamen, indem sie "max key parameter" googelten. max(lis, key=lambda x:int(x))kann vereinfacht werden als max(lis, key=int). Python hat eine eingebaute Funktion, int (). Ebenso können Sie alle anderen integrierten Funktionen als keyArgument verwenden. Zum Beispiel können Sie die längste Zeichenfolge von lis=['a', 'aa', 'aaa']bismax(lis, key=len)
YOUNG
1
@YOUNG Wir können jede Funktion als Schlüsselargument verwenden , können nicht nur eingebauten Funktionen, ist die einzige Bedingung , dass die Funktion der ihm vorbeikam Einzelteile annehmen sollte max, min, sortedetc richtig. Außerdem habe ich max(lis, key=int)gleich am Ende erwähnt. :-)
Ashwini Chaudhary
@ Ashwini Chaudhary .. Angenommen, ich habe eine Liste wie [1,2,3,4,5]. hier sind alle artikel unterschiedlich. Ich verwende die angegebene Funktion max (set (mylist), key = mylist.count), um die häufigsten Elemente zu finden. da es in diesem Fall kein Element gibt, das sich wiederholt. Es wird der niedrigste Artikel zurückgegeben. Können wir etwas tun, damit es in einem solchen Fall Null oder Null zurückgibt?
Vikrant Rana
12

Stark vereinfachte Version von max:

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

In Bezug auf Lambda:

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

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

Wie funktioniert die Max-Funktion?

Es sucht nach dem "größten" Element in einer Iterable. Ich gehe davon aus, dass Sie nachschlagen können, was das ist, aber wenn nicht, können Sie es durchlaufen, dh eine Liste oder eine Zeichenfolge.

Was ist die Verwendung des Schlüsselwortschlüssels in der Max-Funktion? Ich weiß, dass es auch im Zusammenhang mit der Sortierfunktion verwendet wird

Keyist eine Lambda-Funktion, maxdie erkennt , welche Objekte in der Iterable größer sind als andere. Sagen Sie, wenn Sie ein Objekt sortiert haben, das Sie selbst erstellt haben, und nicht etwas Offensichtliches wie Ganzzahlen.

Bedeutung des Lambda-Ausdrucks? Wie lese ich sie? Wie arbeiten Sie?

Das ist eine größere Frage. In einfachen Worten, ist eine Lambda - Funktion kann man herumgehen , und haben andere Teile des Codes verwenden es. Nehmen Sie zum Beispiel:

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

Dies erfordert zwei Objekte aund bund eine Funktion f. Es ruft f()jedes Objekt auf und addiert sie dann. Schauen Sie sich diesen Aufruf an:

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

sum()nimmt 2und ruft den Lambda-Ausdruck darauf auf. So f(a)wird 2 * 2, was 4 wird. Dann tut es dies für bund addiert die beiden zusammen.

In nicht ganz so einfachen Worten stammen Lambdas aus dem Lambda-Kalkül, der Idee einer Funktion, die eine Funktion zurückgibt. Ein sehr cooles mathematisches Konzept zum Ausdrücken von Berechnungen. Sie können darüber lesen hier , und dann tatsächlich verstehen es hier .

Es ist wahrscheinlich besser, etwas mehr darüber zu lesen, da Lambdas verwirrend sein können und es nicht sofort offensichtlich ist, wie nützlich sie sind. Überprüfen Sie hier .

charmlessCoin
quelle
7

maxFunktion wird verwendet, um das Maximum aus einem herauszuholen iterable.

Die Iteratoren können Listen, Tupel, Diktierobjekte usw. oder sogar benutzerdefinierte Objekte sein, wie in dem von Ihnen angegebenen Beispiel.

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.

Das key=funcerlaubt uns also grundsätzlich, ein optionales Argument keyan die Funktion zu übergeben, auf deren Basis der angegebene Iterator / die angegebenen Argumente sortiert und das Maximum zurückgegeben wird.

lambdaist ein Python-Schlüsselwort, das als Pseudofunktion fungiert. Wenn Sie also ein playerObjekt übergeben, wird es zurückgegeben player.totalScore. Somit ist die iterable zu Funktion übergegangen maxwird nach Art zum key totalScore der playerObjekte gegeben und die Rückkehr , playerdas Maximum hat totalScore.

Wenn kein keyArgument angegeben wird, wird das Maximum gemäß den Standardreihenfolgen von Python zurückgegeben.

Beispiele -

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
quelle
6

Laut Dokumentation :

max (iterable [, key])
max (arg1, arg2, * args [, key]) Gibt
das größte Element in einem iterable oder das größte von zwei oder mehr Argumenten zurück.

Wenn ein Positionsargument angegeben wird, muss iterable eine nicht leere iterable sein (z. B. eine nicht leere Zeichenfolge, ein Tupel oder eine Liste). Das größte Element in der Iterable wird zurückgegeben. Wenn zwei oder mehr Positionsargumente angegeben werden, wird das größte der Positionsargumente zurückgegeben.

Das optionale Schlüsselargument gibt eine Ordnungsfunktion mit einem Argument an, wie sie für list.sort () verwendet wird. Das Schlüsselargument muss, falls angegeben, in Schlüsselwortform vorliegen (z. B. max (a, b, c, key = func)).

Dies bedeutet, dass Sie in Ihrem Fall in diesem Fall eine Liste bereitstellen players. Dann maxdurchläuft die Funktion alle Elemente in der Liste und vergleicht sie miteinander, um ein "Maximum" zu erhalten.

Wie Sie sich vorstellen können, ist es bei einem komplexen Objekt wie der playerBestimmung seines Vergleichswertes schwierig, den Wert eines jeden keyzu bestimmen. Daher erhalten Sie das Argument, wie die maxFunktion den Wert jedes Objekts bestimmen soll player. In diesem Fall verwenden Sie eine Lambda-Funktion, um "für jeden pin playersget p.totalscoreund verwenden Sie dies als seinen Vergleichswert" zu sagen .

Inbar Rose
quelle
3

maxist eine eingebaute Funktion, die das erste Argument an nimmt iterable(wie Liste oder Tupel)

Das Schlüsselwortargument keyhat seinen Standardwert None, akzeptiert jedoch die zu bewertende Funktion. Betrachten Sie es als Wrapper, der die iterierbare Funktion basierend auf der Funktion bewertet

Betrachten Sie dieses Beispielwörterbuch:

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

Ex:

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

Wie Sie sehen können key, gibt es den Maximalwert des Schlüssels (alphabetisch) zurück, wenn Sie das iterable nur ohne kwarg (eine Funktion an ) übergeben.

Ex. Anstatt den Maximalwert des Schlüssels alphabetisch zu ermitteln, müssen Sie möglicherweise den Maximalschlüssel anhand der Schlüssellänge ermitteln:

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

In diesem Beispiel gibt die Lambda-Funktion die Länge des Schlüssels zurück, die daher iteriert wird, während Werte ausgewertet werden, anstatt sie alphabetisch zu berücksichtigen. Sie verfolgt die maximale Länge des Schlüssels und gibt den Schlüssel mit der maximalen Länge zurück

Ex.

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

In diesem Beispiel gibt die Lambda-Funktion den Wert des entsprechenden Wörterbuchschlüssels zurück, der den Maximalwert hat

Gahan
quelle