Tach auch,
1.
manchmal liest man hier im Forum sowas wie in der Überschrift.
Meine Frage nun ist, ob damit gemeint ist, das Konstrukte wie
lambda oder map/filter benutzt werden.
Beim Lesen könnte man den Eindruck bekommen, funktionale
Konstrukte in Python seien irgendwie "besser".
2.
Jemand hat mir mal auf den Konstrukt:
liste.remove()
geantwortet, das wäre nicht besonders toll, weil ne Menge Daten hin- und herkopiert werden müssten.
Als alter C Programmierer hätte ich gedacht, das eine Liste in Python
über sowas wie eine verkettete Liste abgebildet wird; und da sind
solche Dinge ja billig (im Sinne von CPU/Speicher).
Bin für jeden Kommentar dankbar.
Wann "liest" sich Python funktional und noch ne Kl
Zu reiner funktionalen Programmierung gehören: a) Funktionen die keine Seiteneffekte haben, d.h. Werte kommen als Argumente in eine Funktion hinein und verlassen sie als Rückgabewert, sonst verändert die Funktion nichts "ausserhalb". Und b) das Funktionen "first class objects" sind, also als Argumente übergeben werden können und als Rückgabewerte möglich sind. `map()` und `filter()` sind dafür typische Beispiele.sunmountain hat geschrieben:1.
manchmal liest man hier im Forum sowas wie in der Überschrift.
Meine Frage nun ist, ob damit gemeint ist, das Konstrukte wie
lambda oder map/filter benutzt werden.
Beim Lesen könnte man den Eindruck bekommen, funktionale
Konstrukte in Python seien irgendwie "besser".
Ob funktionale Programmierung nun besser (als was?) ist, kann man nicht so pauschal sagen. Ich mag diese Art zu programmieren ganz gerne. Man entwirft Programme in einzelnen Funktionen, die dann mit den Funktionen `map()`, `filter()` bzw. den Gegenstücken in `itertools` zu einer Lösung zusammengesetzt werden können.
Dabei muss man in Python nicht rein funktional bleiben, sondern kann beliebig OOP und prozedurale Konzepte verwenden, je nachdem was am besten auf das Problem passt.
Einen Vorteil haben die Funktionen in `itertools` in Bezug auf Speicherverbrauch, weil "Zwischenergebnisse" nur berechnet werden, wenn sie benötigt werden. Es gibt funktionale Sprachen, bei denen das automatisch so gemacht wird -- nennt sich "lazy evaluation".
Denk als alter C-Programmierer besser an ein dynamisch angelegtes Array, das bei Bedarf mit`realloc()` schrumpft oder wächst.2.
Jemand hat mir mal auf den Konstrukt:
liste.remove()
geantwortet, das wäre nicht besonders toll, weil ne Menge Daten hin- und herkopiert werden müssten.
Als alter C Programmierer hätte ich gedacht, das eine Liste in Python
über sowas wie eine verkettete Liste abgebildet wird; und da sind
solche Dinge ja billig (im Sinne von CPU/Speicher).
Was mir an Python sehr gefällt - manche Sachen lassen sich mit funktionalen Elementen sehr einfach und intuitiv ausdrücken, während wirklich rein funktionale Sprachen sich dagegen für die meisten zumindest sehr ungewohnt lesen.BlackJack hat geschrieben:Dabei muss man in Python nicht rein funktional bleiben, sondern kann beliebig OOP und prozedurale Konzepte verwenden, je nachdem was am besten auf das Problem passt.
Pylint beschwert sich übrigens standardmäßig, wenn man "map" oder "filter" verwendet, da die Listcomprehension anscheinend effizienter ist und sich IMHO auch intuitiver lest - zumindest bei "filter" ist mir das auch schon einmal selbst aufgefallen, da ich eigentlich angenommen hätte, dass die filter-variante effizienter ist
lambda alleine muss denk ich noch nicht heißen, dass es funktional ist, nur wird das üblicherweise bei "map", etc. verwendet und definiert so einfache Funktionen, die keine Seiteneffekte haben. (Habe gerade getestet: lambda-Statements können zumindest keine Zuweisungen enthalten, aber natürlich anderen Code aufrufen, der Seiteneffekte enthält)Meine Frage nun ist, ob damit gemeint ist, das Konstrukte wie
lambda oder map/filter benutzt werden.
http://de.wikipedia.org/wiki/Funktionale_Programmierung
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
Die Warnung ist nicht auf Effizienz bezogen sondern auf Guido's (juhuu ein "Deppenapostroph") Ansinnen die beiden Funktionen in Python 3000 aus den Builtins verschwinden zu lassen. Dann werden sie aber sicher in einem Modul wieder auftauchen. Wenn sinnvoll verwende ich sowieso `itertools.imap()` und `itertools.ifilter()`.Luzandro hat geschrieben:Pylint beschwert sich übrigens standardmäßig, wenn man "map" oder "filter" verwendet, da die Listcomprehension anscheinend effizienter ist und sich IMHO auch intuitiver lest - zumindest bei "filter" ist mir das auch schon einmal selbst aufgefallen, da ich eigentlich angenommen hätte, dass die filter-variante effizienter ist
Ansonsten wird die entsprechende Warnung von PyLint auch für `apply()` und `input()` erzeugt. Da ich ziemlich sicher bin, dass ich beide nicht verwende, habe ich diese Warnung (W0141) einfach abgeschaltet.
Ja Leider :/ Und leider auch nicht die einzigen Sachen. Unteranderem auch ``reduce`. Wenigstens wie lambda nicht gekillt. Für lambda wollte er ja was besseres finden und hat (wer hätte es erwartet ) auch nichts gefunden.
http://www.python.org/dev/peps/pep-3100 ... -namespace
Warum macht GvR so ein scheiß? Eins weiß ich, wenn von dem geplanten wirklich alles umgesetzt wird, dann hat sich das Thema Python für mich erledigt. Das ``itervalues`` gekillt wird, kann ich gerade eben so verkraften, wobei ich die Begründung von Guido ein wenig...naja...
EDIT: Warum muss er unbedingt die Funktionalen Sachen aus den Builtins rausnehmen? LCs sind ja schön und gut, aber wenn ich die Wahl habe nehmen ich ``map`` bzw. ``itertools.imap`` etc. anstatt mir eine Lange LC zu bauen.
http://www.python.org/dev/peps/pep-3100 ... -namespace
Warum macht GvR so ein scheiß? Eins weiß ich, wenn von dem geplanten wirklich alles umgesetzt wird, dann hat sich das Thema Python für mich erledigt. Das ``itervalues`` gekillt wird, kann ich gerade eben so verkraften, wobei ich die Begründung von Guido ein wenig...naja...
EDIT: Warum muss er unbedingt die Funktionalen Sachen aus den Builtins rausnehmen? LCs sind ja schön und gut, aber wenn ich die Wahl habe nehmen ich ``map`` bzw. ``itertools.imap`` etc. anstatt mir eine Lange LC zu bauen.
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Hisape hat geschrieben:Warum macht GvR so ein scheiß? Eins weiß ich, wenn von dem geplanten wirklich alles umgesetzt wird, dann hat sich das Thema Python für mich erledigt. Das ``itervalues`` gekillt wird, kann ich gerade eben so verkraften, wobei ich die Begründung von Guido ein wenig...naja...
EDIT: Warum muss er unbedingt die Funktionalen Sachen aus den Builtins rausnehmen? LCs sind ja schön und gut, aber wenn ich die Wahl habe nehmen ich ``map`` bzw. ``itertools.imap`` etc. anstatt mir eine Lange LC zu bauen.
Warum stört dich das itervalues gelöscht wird? values ist dann ja genau dasselbe (ein Iterator wird zurückgegeben).
Und wegen den LCs, du kannst ja weiterhin itertools.imap (was ja sowieso nie in den Builtins war) nehmen, LCs sind für mich lesbarer als map und somit finde ich das berechtigt um map aus den Builtins zu löschen. Was nicht heisst dass es ganz gelöscht wird, in einem Modul wird es sicher weiterhin vorhanden sein.
Gruss
Mich stört es. Warum? Einfach deswegen, was gleich folgt.
Generel:
Aber mal generell: Als begründung wird geliefert das man eine ``map`` Konstruktion auch mit eine LC machen kann.
Ja, hast du mal gesehen wie das mit einer Anonymen Funktion aussieht?
Cool, nicht nur das ich die Anonyme Funktion in runden Klamern
setzen muss; Neine ich muss auch noch einen Aufruf forcieren weil
Python zu dumm ist das Argument der for Iteration direkt an die
Anonymen Funktion zu überliefern -> ``(lambda x: str(x) + 'spam')(x)`` <-- Man beachte die Forcierung mit ``(x)``
Schön. Und das ist nun lesbarer als ``print map(lambda x: str(x) + 'spam', test)``?
Sorry, ich war bisher großer Fan von Python, aber das was alles geplant ist mit Py3K lässt mich nun Zweifeln ob ich mich für die richtige Sprache entschieden habe.
Generel:
Code: Alles auswählen
from itertools import imap
test = [1, 2, 3]
# Mit ``map``.
print map(lambda x: str(x) + 'spam', test)
# Da ``imap`` nen iterator zurückliefert muss man es z.B. mit ``list``
# aufrufen. Ist ja nicht so wild....
print list(imap(lambda x: str(x) + 'spam', test))
Ja, hast du mal gesehen wie das mit einer Anonymen Funktion aussieht?
Code: Alles auswählen
print [(lambda x: str(x) + 'spam')(x) for x in test]
setzen muss; Neine ich muss auch noch einen Aufruf forcieren weil
Python zu dumm ist das Argument der for Iteration direkt an die
Anonymen Funktion zu überliefern -> ``(lambda x: str(x) + 'spam')(x)`` <-- Man beachte die Forcierung mit ``(x)``
Schön. Und das ist nun lesbarer als ``print map(lambda x: str(x) + 'spam', test)``?
Sorry, ich war bisher großer Fan von Python, aber das was alles geplant ist mit Py3K lässt mich nun Zweifeln ob ich mich für die richtige Sprache entschieden habe.
Ja, aber oft brauche ich kein iterator und finde es blöd dann ``list(imap(...))`` zu schreiben, und verwende dann lieber gleich ``map(...)``rayo hat geschrieben: Und wegen den LCs, du kannst ja weiterhin itertools.imap (was ja sowieso nie in den Builtins war) [...]
EDIT: @All: Nicht falsch verstehen, es sind halt ein par Sachen an die ich mich gewöhnt habe und sehr nützlich finde, die nun mit Py3K weckkommen und das stört mich ein wenig :-[
Zuletzt geändert von sape am Montag 15. Januar 2007, 10:39, insgesamt 1-mal geändert.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Und? Wie oft hast du `reduce` schon verwendet?sape hat geschrieben:Ja Leider :/ Und leider auch nicht die einzigen Sachen. Unteranderem auch ``reduce`.
Übrigens: PEP 3100 ist wie alle 3xxx-PEPs im Fluss. Alle paar Tage wird eine neue Ergänzung oder Ersetzung vorgenommen.Wenigstens wie lambda nicht gekillt. Für lambda wollte er ja was besseres finden und hat (wer hätte es erwartet ) auch nichts gefunden.
http://www.python.org/dev/peps/pep-3100 ... -namespace
Leider wird das GvR nicht interessierenWarum macht GvR so ein scheiß? Eins weiß ich, wenn von dem geplanten wirklich alles umgesetzt wird, dann hat sich das Thema Python für mich erledigt.
Ehrlich, es ist ja nicht so als ob Python 3.0 morgen vor der Tür stände. Dieses Jahr gibt es eine erste Alpha, und bis zum endgültigen Release vergeht mindestens dann noch ein Jahr. Und wer weiß, vielleicht gibt es ja auch ein paar neue Features, die dich überraschen?
2.x wird noch eine ziemlich lange Zeit gepflegt werden, denn es ist natürlich nicht so einfach, größere Projekte umzustellen.
Was hast du daran nicht verstanden? Wenn `values()` schon einen Iterator (oder eine View) zurückgibt, ist `itervalues()` überflüssig.Das ``itervalues`` gekillt wird, kann ich gerade eben so verkraften, wobei ich die Begründung von Guido ein wenig...naja...
"lang" ist übertrieben. Und es spricht ja nichts gegen "from itertools import imap".EDIT: Warum muss er unbedingt die Funktionalen Sachen aus den Builtins rausnehmen? LCs sind ja schön und gut, aber wenn ich die Wahl habe nehmen ich ``map`` bzw. ``itertools.imap`` etc. anstatt mir eine Lange LC zu bauen.
und wofür genau brauchst du da ein lambda?sape hat geschrieben:Code: Alles auswählen
print [(lambda x: str(x) + 'spam')(x) for x in test]
Code: Alles auswählen
['%sspam' % x for x in test]
[str(x) + 'spam' for x in test]
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
LOL. LCs sind ja gerade deshalb da, um lambdas zu vermeiden. Wenn du natürlich mit aller Gewalt eines einbaust, kann die LC nichts dafür...sape hat geschrieben: Ja, hast du mal gesehen wie das mit einer Anonymen Funktion aussieht?Cool, nicht nur das ich die Anonyme Funktion in runden KlamernCode: Alles auswählen
print [(lambda x: str(x) + 'spam')(x) for x in test]
setzen muss; Neine ich muss auch noch einen Aufruf forcieren weil
Python zu dumm ist das Argument der for Iteration direkt an die
Anonymen Funktion zu überliefern -> ``(lambda x: str(x) + 'spam')(x)`` <-- Man beachte die Forcierung mit ``(x)``
Schön. Und das ist nun lesbarer als ``print map(lambda x: str(x) + 'spam', test)``?
Code: Alles auswählen
print [str(x) + 'spam' for x in test]
sape, du ueberzeugst mich...
ist doch viel besser als ein map, weil kein lambda drin steckt und die "for...in" sache machts fuer menschen auch ohne wissen um map und filter verstaendlich.
Code: Alles auswählen
print [str(x) + 'spam' for x in test]
...meh...
Ich ahb daran alles verstanden, aber du meine Post offensichtlich nicht. Es geht nicht darum das es dann überflüssig ist, sondern das man alle Codes die bisher im Netzt sind dann ändern muss.birkenfeld hat geschrieben: Was hast du daran nicht verstanden? Wenn `values()` schon einen Iterator (oder eine View) zurückgibt, ist `itervalues()` überflüssig.
Nö, schau dir doch den vergleich ob von mir zwischen map (bzw. imap) und der Entsprechenden LC an? Wenn das nicht lang ist weiß ich auch nicht.birkenfeld hat geschrieben: "lang" ist übertrieben. Und es spricht ja nichts gegen "from itertools import imap".
``print map(lambda x: str(x) + 'spam', test)`` VS. ``print [(lambda x: str(x) + 'spam')(x) for x in test]``
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Mal ganz grundsätzlich: Python 3.0 wird eine nichtrückwärtskompatible Revision von Python. Du kannst nicht einfach erwarten, Code für 2.x unter 3.x laufen zu lassen.sape hat geschrieben:Weil zu 99.9% von allem Code der im Netzt rumfliegt ``itervalus`` nutzt, wenn über die Keys+ Values von nem ``dict``iteriert wird?rayo hat geschrieben: Warum stört dich das itervalues gelöscht wird?
Dafür wird es aber ein automatisiertes Tool geben, das alte Syntax und alte Funktionen in neue Syntax und neue Funktionen umschreibt.
Und da `itervalues` nun bestimmt kein häufiger Methodenname für Klassen (die nicht von `dict` erben) ist, hält sich die Anzahl falscher Treffer sicher in engen Grenzen.
Zuletzt geändert von birkenfeld am Montag 15. Januar 2007, 10:44, insgesamt 1-mal geändert.
Ehm, das mit dem inenren Teil von dem lambda war nur ein Beispiel. Normalerweise sind da Komplexere Ausdrücke, die man nicht so wie in deinem Beislpiel abkürzen kann.cracki hat geschrieben:sape, du ueberzeugst mich...
ist doch viel besser als ein map, weil kein lambda drin steckt und die "for...in" sache machts fuer menschen auch ohne wissen um map und filter verstaendlich.Code: Alles auswählen
print [str(x) + 'spam' for x in test]
<offtopic>
sape, da hab ich noch ne frage zu:
http://www.python-forum.de/post-55407.html#55407
</offtopic>
sape, da hab ich noch ne frage zu:
http://www.python-forum.de/post-55407.html#55407
</offtopic>
...meh...
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Doch, das kann man immer.sape hat geschrieben:Ehm, das mit dem inenren Teil von dem lambda war nur ein Beispiel. Normalerweise sind da Komplexere Ausdrücke, die man nicht so wie in deinem Beislpiel abkürzen kann.
map(lambda x: expr(x), seq) ist immer äquivalent zu [expr(x) for x in seq].
map(func, seq) ist immer äquivalent zu [func(x) for x in seq].
``map`` einspricht ``[f(x) for x in seq]``birkenfeld hat geschrieben: LOL. LCs sind ja gerade deshalb da, um lambdas zu vermeiden.Code: Alles auswählen
print [str(x) + 'spam' for x in test]