Provisorischer lambda, reduce(), filter() und map() Ersatz

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
akis.kapo
User
Beiträge: 127
Registriert: Freitag 1. September 2006, 12:58

Hi all,

ich hab heute eher ne Diskussion und weniger ne technische Frage.

Es ist ja bekannt, dass Python auf kurz oder lang das "lambda" keyword verlieren wird und reduce(), filter() und map() sollen auch bald ersatzlos gestichen werden.

Quelle: http://www.artima.com/weblogs/viewpost.jsp?thread=98196
Der Artikel ist alt (2005), das Thema ist also schon länger bekannt.

In Python 3.4 (development, Stand 24.02.2014) sind trotzdem noch alle o.g. features drin, komischerweise.

Aber angenommen, man will jetzt schon anfangen, umzudenken, ... wie macht man das am besten?

Aus einem Blog von Guido hab ich schon die pythonichen Pendants zu filter() und map():

Code: Alles auswählen

def filter(func, data):
    return [x for x in data if func(x)],

Code: Alles auswählen

def map(func, data):
    return [func(x) for x in data]
Wie ihr seht, sind die beiden noch einfach umzusetzen. Beides Einzeiler...

Und was mach ich mit lambda und reduce? Irgendwo hab ich gelesen man soll einfach innere Funktionen für lambda nutzen, je nachdem wo man es braucht. Ansonsten, wenn man dieselbe Lambda-Funktion an mehreren Stellen braucht, soll man ne ganz normale Funktion draus bauen und fertig. Das Konzept von lambda in Python ist mir sowieso nicht ganz klar. So, wie ich das sehe ist das nur ne andere Schreibweise, die darauf ausgelegt ist, kurz und knapp zu sein (zwingend eine Zeile, sonst syntax error) - mächtiger wird Python dadurch nicht. Da verstehe selbst ich, wieso man was dagegen hat, für so ein pille-palle feature ein keyword zu verwenden. Aber vielleicht kann jemand ein sinnvolles Beispiel nennen, wie man ein lambda umgeht, und trotzdem elegant und knapp bleibt?

Ausserdem ist mir noch aufgefallen, dass das builtin-map() ca. 50% schneller ist, als die selbstgebastelte-map().
Ich kann ja verstehn, wieso man map() aus Prinzip oder wegen Redundanz weg haben will, aber will man wirklich -50% Performance deswegen einbußen?
Und wenn nein, wie gedenken die Entwickler, nochmals 50% mehr performance bei "[func(x) for x in data]" rauszuquetschen, als ohnehin schon.

Und zu reduce() hab ich ehrlich gesagt überhaupt keine sentimentalen Gefühle, das hab ich höchstens für Addierung oder XOR von irgendwelchen Listen gebraucht und für sonst nix.
Dennoch hab ich ne Hirnblockade für reduce() eine elegante Reimplementierung auszudenken, ohne Listen und .append() zu verwenden und Objekte immer wieder zu überschreiben/reassignen.

Ich habe mich nicht ausreichend mit 3.x befasst (aus Faulheit und Bequemlichkeit) und sollte es aber bald, daher an dieser Stelle die Diskussion:

A) Wie würdet ihr die fehlenden features lambda, reduce(), filter(), map() in Python implementieren/verwenden?
B) Welche features entfallen noch in Zukunft von denen ich noch nichts weiss (gibt's vielleicht ne komplett-Übersicht über Features, die definitv über Board geworfen werden?)*
C) Wie würde man features aus B) in Python implementieren/verwenden?
D) Wie rechtfertig man (oder umgeht) den Performanceverlust (siehe Beispiel map())?

Bin froh über alle hilfreichen Meinungen, Antworten, Links, ... zum Thema.

*) Stattdessen hab ich hier ne Liste von features gefunden, die definitiv in Python bleiben. xD (Genau das Gegenteil, von was ich suche!) :lol:
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

akis.kapo hat geschrieben:Es ist ja bekannt, dass Python auf kurz oder lang das "lambda" keyword verlieren wird und reduce(), filter() und map() sollen auch bald ersatzlos gestichen werden.
Das ist so nicht korrekt. Guido wollte diese Features in Python 3 entfernen, hat sich damit aber nicht durchsetzen können (reduce, filter, map).
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

akis.kapo hat geschrieben:Es ist ja bekannt, dass Python auf kurz oder lang das "lambda" keyword verlieren wird und reduce(), filter() und map() sollen auch bald ersatzlos gestichen werden.
Bekannt ist da gar nichts. Es gibt zwar Leute in der Python Community die zumindest von lambda und reduce keine Fans und dazu gehört auch Guido aber trotzdem ist mit Python 3 nur reduce nach functools verschoben worden. Konkrete Pläne die zu entfernen gibt es damit nicht und wenn überhaupt wäre dies auch nicht "bald" sondern erst mit einem hypothetischen Python 4 möglich, falls dann jemand eine entsprechende PEP schreibt und falls sich dann eine Mehrheit findet oder Guido ernsthaft seine Macht als BDFL nutzt um in diesem Punkt seine Meinung durchzusetzen.

Python 3 wird erst so langsam angenommen und ist inzwischen mehr als 4 Jahre alt, betrachtet man die Support Zeiten von so einigen Betriebssystemen kann man davon ausgehen, dass Python 3 vor 2020 - tendenziell eher später - nicht dominieren wird. Also würde ich davon ausgehen dass Python 4 frühestens 2030 ein ernsthaftes Thema wird. Angenommen natürlich Python 4 wird es überhaupt geben.
BlackJack

@akis.kapo: So schwer ist das mit reduce doch nicht (ungetestet):

Code: Alles auswählen

_NOTHING = object()

def reduce(function, iterable, initial=_NOTHING):
    items = iter(iterable)
    result = next(items) if initial is _NOTHING else initial
    for item in items:
        result = function(result, item)
    return result
Ich denke die Frage war/ist was passiert wenn die Funktionen wirklich aus der Standardbibliothek verschwinden. Mein Tipp: Jemand implementiert ein C-Modul mit eben diesen Funktionen aus dem vorhandenen Quelltext. Und wenn sich das dann viele Leute installieren, wäre es ein guter Kandidat für die Standardbibliothek. Ich denke diese dumme Situation wollten die Entwickler letztendlich vermeiden.

Zur Zeitmessung: 50% hört sich jetzt erst einmal viel an, aber was *macht* denn Dein Test in der Schleife mit den Elementen? Je länger das dauert, desto kleiner wird der Anteil der zusätzlichen Zeit die gegenüber `map()` benötigt wird.

Bei Bibliotheken die Rückruffunktionen brauchen kann ich mir Python ohne Lambda-Ausdruck schlecht vorstellen. Zum Beispiel GUI-Rahmenwerke. Da sieht man das öfter. Wenn man stattdessen jedes mal eine Funktion mit einem unnötigem Namen definieren müsste, würde das IMHO schon irgendwann nervig.

Beim verlinkten Artikel von 2005 steht doch sogar in Fett gesetzt das die Sachen in Python 3 nicht verschwinden werden‽
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

akis.kapo hat geschrieben:Das Konzept von lambda in Python ist mir sowieso nicht ganz klar. So, wie ich das sehe ist das nur ne andere Schreibweise, die darauf ausgelegt ist, kurz und knapp zu sein (zwingend eine Zeile, sonst syntax error) - mächtiger wird Python dadurch nicht. Da verstehe selbst ich, wieso man was dagegen hat, für so ein pille-palle feature ein keyword zu verwenden.
Es vereinfacht die Schreibweise von vielen Konstrukten die eine Funktion als Argument erwarten. Wenn diese Funktion nur einmal verwendet werden soll, bieten sich dort anonyme Funktionen an, da man nicht den Namensraum mit einer unnützen Definition beglücken will.

Das Feature ist übrigens so pille-palle dass sogar Java mit Version 8 lambda-Ausdrücke bekommt, C++ is deswegen dank C++11 noch unleserlicher als vorher und auch Apple hat C für ObjC um Blöcke erweitert. </ironie> Insofern hätte es mich eigentlich wirklich nicht gewundert, dass Python3 lambda killt, aber offenbar hat da doch jemand ein einsehen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

akis.kapo hat geschrieben:Das Konzept von lambda in Python ist mir sowieso nicht ganz klar. So, wie ich das sehe ist das nur ne andere Schreibweise, die darauf ausgelegt ist, kurz und knapp zu sein (zwingend eine Zeile, sonst syntax error) - mächtiger wird Python dadurch nicht.
Wenn du so argumentierst, dann könnte man noch vieles Streichen. for ist nur ein Spezialfall von while, statt LCs könntest du Schleifen verwenden, Klassen können auf einfachere Strukturen abgebildet werden und Variablen sind eigentlich nur Speicheradressen mit ein wenig Zusatz. Und wenn man es ganz genau nimmt, dann ist das def-Statement nur eine Kurzschreibweise für das Binden von lambda-Ausdrücken an einen Namen ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

EyDu hat geschrieben:Und wenn man es ganz genau nimmt, dann ist das def-Statement nur eine Kurzschreibweise für das Binden von lambda-Ausdrücken an einen Namen ;-)
Wenn man es wirklich ganz genau nimmt, dann nicht :P Zumindest nicht in Python :roll:
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

cofi hat geschrieben:Wenn man es wirklich ganz genau nimmt, dann nicht :P Zumindest nicht in Python :roll:
Python ist doch nur eine kürzere Schreibweise für den Lambda-Kalkül ;-)
Das Leben ist wie ein Tennisball.
Antworten