lambda-Ausdrücke mit mehreren Parametern in Python
Einführendes Beispiel
lambda-Funktionen können mehrere Parameter haben, deren Namen im lambda-Ausdruck durch ein Komma voneinander getrennt werden.
Eine lambda-Funktionen muß mit derselben Anzahl an Argumenten aufgerufen werden, wie sie an Parameter hat.
Bei einer Inkarnation einer lambda-Funktion mit Argumentwerten steht dann ein eventueller erster Parameter dann für einen eventuellen ersten Argumentwert, ein eventueller zweiter Parameter dann für einen eventuellen zweiten Argumentwert und so weiter.
Das folgende Beispiel zeigt eine lambda-Funktion, welche die Summe ihrer Argumentwerte (»x« und »y«) ergibt: »lambda x, y: x+y«.
- Protokoll
( lambda x, y: x+y )( 7, 2 )
9
Interessanterweise kann dieselbe Funktion auch als Zeichenfolgenverbindung interpretiert werden.
- Protokoll
( lambda x, y: x+y )( 'abc', 'def' )
'abcdef'
Eine Funktion, welche die Summe ihrer Argumentwerte («x» und «y») ergibt: ›lambda x, y: x+y‹.
- Protokoll
f = lambda x, y: x+y
f( 7, 2 )
9
- Protokoll
f( '7', '2' )
'72'
Syntax
- Neue, erweiterte Syntax (vereinfacht)
lambda-Ausdruck
.--------------------------------------------.
| |
.------. | .--------------------------. V .-. .----------.
--->( lambda )---'---.--->| gewoehnlicher Bezeichner |--->.---'--->( : )--->| Ausdruck |--->
'------' ^ '--------------------------' | '-' '----------'
| .-. |
'----------------( , )---------------'
'-'
Anforderungen
Jeder Name darf in der Liste nur einmal vorkommen.
Semantik
In der Inkarnation einer lambda-Funktion ergibt eine Auswertung jedes Parameternamens den Wert des Arguments des Aufrufes an der gleichen Position.
So ergibt »( lambda x, y: x+y )( 7, 2 )« beispielsweise »7 + 2«
Beispiel
Der KMI (Körper-Masse-Index ) ist die durch das Quadrat der Größe geteilte Masse eines Menschen.
- KMI-Berechnung
77 / 1.73 ** 2
25.727555214006482
Eine lambda-Funktion erlaubt es, die Berechnungsvorschrift von den konkreten Zahlenwerten zu trennen – eines der Grundprinzipien der Programmierung.
Dadurch kann die Berechnungsvorschrift verdeutlicht werden, und es wird erleichtert, die konkreten Zahlenwerte zu verändern.
- KMI -Berechnung
( lambda masse, groesse: masse / groesse ** 2 )( 77, 1.73 )
25.727555214006482
- KMI -Berechnung
( lambda masse, groesse: masse / groesse ** 2 )( 78, 1.81 )
23.808797045267237
- KMI -Berechnung
( lambda masse, groesse: masse / groesse ** 2 )( 62.6, 1.68 )
22.179705215419506
Durch die Bindung eines Namens an die lambda-Funktion kann die Trennung noch weiter getrieben werden.
- KMI -Berechnung
kmi = lambda masse, groesse: masse / groesse ** 2
kmi( 77, 1.73 )
25.727555214006482
Gute, verständliche, aber nicht zu lange Namen für Objekte sind sehr wichtig, weil sie deren Bedeutung sofort verständlich machen. »kmi« ist ein Beispiel für einen solchen Namen (falls man davon ausgehen kann, daß die Projektbeteiligten diese Bezeichnung kennen).
- KMI -Berechnung
kmi( 78, 1.81 )
23.808797045267237
- KMI -Berechnung
kmi( 62.6, 1.68 )
22.179705215419506
Außerdem können wir mit der lambda-Schreibweise den in der Berechnung vorkommenden Größen Namen geben und ihre Bedeutung so erkennbar machen. Es ist auch noch erlaubt, die Argumente mit den Paramternamen zu etikettieren, wie in dem folgenden Beispiel gezeigt wird:
- KMI -Berechnung
( lambda masse, groesse: masse / groesse ** 2 )( masse=62.6, groesse=1.68 )
22.179705215419506
- KMI -Berechnung
kmi( masse=62.6, groesse=1.68 )
22.179705215419506
Die Etikettierung verhindert Verwechslungen bei der Zuordnung von Argumentwerten zu Parametern.
Bei der Etikettierung wird ein Parametername mit einem Gleichheitszeichen getrennt vor einen Argumentausdruck geschrieben. Dabei wird empfohlen, keine Leerzeichen vor oder hinter das Gleichheitszeichen zu schreiben.
Bedingte Auswertungen
- Konsolenprotokoll
when = lambda condition, expression: condition and expression() or None
when( False, lambda: print( "*" ))
when( True, lambda: print( "*" ))
*
- Konsolenprotokoll
when_not = lambda condition, expression:( condition or expression() )and None
when_not( False, lambda: print( "*" ))
*
when_not( True, lambda: print( "*" ))
Übungsfragen
? Übungsfrage
Welche Werte haben die folgenden Aufrufe?
- Eingaben
wenn = lambda wenn, dann, sonst: wenn * dann +( 1 - wenn )* sonst
wenn( False, 12, -7 )
wenn( True, 12, -7 )
Übungsaufgaben ⃖
/ Übungsaufgabe ⃖
Schreiben Sie eine Funktion »p« zur Berechnung des Produkts ihrer beiden Argumentwerte. (Man kann hierbei davon ausgehen, daß die Funktion immer mit numerischen Argumentwerten aufgerufen wird, die zwischen «0» und «1000» liegen.)
- Auswertung
p( 2, 3 )
6
Die Lösung könnte beispielsweise mit »p = lambda x, y:« beginnen.
/ Übungsaufgabe ⃖ °
Schreiben Sie eine Funktion »m« zur Berechnung des Mittelwertes ihrer beiden Argumentwerte. (Man kann hierbei davon ausgehen, daß die Funktion immer mit numerischen Argumentwerten aufgerufen wird, die zwischen «0» und «1000» liegen.)
- Auswertung
m( 2, 3 )
2.5
/ Übungsaufgabe ⃖ °
Schreiben Sie eine Funktion »teiler«, die ergibt, ob das erste Argument durch das zweite geteilt werden kann.
- Auswertung
teiler( 12, 2 )
True
- Auswertung
teiler( 12, 5 )
False
/ Übungsaufgabe °
Schreiben Sie eine Funktion zur Berechnung des Logarithmus einer Zahl zu einer Basis. Dabei soll die Basis durch den erste Parameter repräsentiert werden und die Zahl durch den zweiten. Verwenden Sie hierzu die Funktion »log« aus dem Modul »math«, bei der allerdings die Zahl durch den ersten Parameter repräsentiert wird und die Basis durch den zweiten.
/ Übungsaufgabe °
Schreiben Sie ein Programm, welches Masse und Größe einliest und den entsprechenden Körper-Masse-Index KMI ausgibt.
- Das Programm soll also nach dem Start anhalten und auf die Eingabe der Daten durch den Benutzer warten. Alsdann soll es den entsprechenden KMI so ausgeben, daß der Benutzer des Programms ihn lesen kann.
Hintereinanderausführung mit »lambda« *
Die Funktion «compose» ergibt eine Funktion, welche aus der Hintereinanderausführung ihrer beiden Argument besteht (vorausgesetzt, die erste Funktion kann mit einem Argument aufgerufen werden und die zweite ohne Argumente). »compose( int, input )« ist damit wie »lambda: int( input() )«
- Protokoll
compose = lambda f, g: lambda: f( g() )
read_int = compose( int, input )
read_int() + read_int()
2
4
6
/ Teilweise Anwendung von Funktionen *
Schreiben Sie eine Funktion »apply«, welche die Anwendung eines Aufrufbaren mit zwei Argumenten auf ein Argument erlaubt, so daß sich danach ein Aufrufbares mit einem Argument ergibt.
- Beispiele
from operator import add
inc = apply( add, 1 )
inc( 3 )
4