Wann "liest" sich Python funktional und noch ne Kl

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.
Benutzeravatar
sunmountain
User
Beiträge: 89
Registriert: Montag 13. März 2006, 17:18

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.
BlackJack

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".
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.

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".
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).
Denk als alter C-Programmierer besser an ein dynamisch angelegtes Array, das bei Bedarf mit`realloc()` schrumpft oder wächst.
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

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.
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.

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
Meine Frage nun ist, ob damit gemeint ist, das Konstrukte wie
lambda oder map/filter benutzt werden.
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)

http://de.wikipedia.org/wiki/Funktionale_Programmierung
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
BlackJack

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

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.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

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 :roll:) 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... :roll:


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.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

sape 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... :roll:


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.
Hi

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
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Mich stört es. Warum? Einfach deswegen, was gleich folgt.

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))
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? :roll:

Code: Alles auswählen

print [(lambda x: str(x) + 'spam')(x)  for x in test]
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 :roll: -> ``(lambda x: str(x) + 'spam')(x)`` <-- Man beachte die Forcierung mit ``(x)`` :roll:

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.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

rayo hat geschrieben: Warum stört dich das itervalues gelöscht wird?
Weil zu 99.9% von allem Code der im Netzt rumfliegt ``itervalus`` nutzt, wenn über die Keys+ Values von nem ``dict``iteriert wird?
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

rayo hat geschrieben: Und wegen den LCs, du kannst ja weiterhin itertools.imap (was ja sowieso nie in den Builtins war) [...]
Ja, aber oft brauche ich kein iterator und finde es blöd dann ``list(imap(...))`` zu schreiben, und verwende dann lieber gleich ``map(...)`` :)

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

sape hat geschrieben:Ja Leider :/ Und leider auch nicht die einzigen Sachen. Unteranderem auch ``reduce`.
Und? Wie oft hast du `reduce` schon verwendet?
Wenigstens wie lambda nicht gekillt. Für lambda wollte er ja was besseres finden und hat (wer hätte es erwartet :roll:) auch nichts gefunden.

http://www.python.org/dev/peps/pep-3100 ... -namespace
Übrigens: PEP 3100 ist wie alle 3xxx-PEPs im Fluss. Alle paar Tage wird eine neue Ergänzung oder Ersetzung vorgenommen.
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.
Leider wird das GvR nicht interessieren ;)
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.
Das ``itervalues`` gekillt wird, kann ich gerade eben so verkraften, wobei ich die Begründung von Guido ein wenig...naja... :roll:
Was hast du daran nicht verstanden? Wenn `values()` schon einen Iterator (oder eine View) zurückgibt, ist `itervalues()` überflüssig.
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.
"lang" ist übertrieben. Und es spricht ja nichts gegen "from itertools import imap".
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

sape hat geschrieben:

Code: Alles auswählen

print [(lambda x: str(x) + 'spam')(x)  for x in test]
und wofür genau brauchst du da ein lambda?

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]
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

sape hat geschrieben: Ja, hast du mal gesehen wie das mit einer Anonymen Funktion aussieht? :roll:

Code: Alles auswählen

print [(lambda x: str(x) + 'spam')(x)  for x in test]
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 :roll: -> ``(lambda x: str(x) + 'spam')(x)`` <-- Man beachte die Forcierung mit ``(x)`` :roll:

Schön. Und das ist nun lesbarer als ``print map(lambda x: str(x) + 'spam', test)``?
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...

Code: Alles auswählen

print [str(x) + 'spam'  for x in test]
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

sape, du ueberzeugst mich...

Code: Alles auswählen

print [str(x) + 'spam' for x in test]
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.
...meh...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

birkenfeld hat geschrieben: Was hast du daran nicht verstanden? Wenn `values()` schon einen Iterator (oder eine View) zurückgibt, ist `itervalues()` überflüssig.
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: "lang" ist übertrieben. Und es spricht ja nichts gegen "from itertools import imap".
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.

``print map(lambda x: str(x) + 'spam', test)`` VS. ``print [(lambda x: str(x) + 'spam')(x) for x in test]``
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

sape hat geschrieben:
rayo hat geschrieben: Warum stört dich das itervalues gelöscht wird?
Weil zu 99.9% von allem Code der im Netzt rumfliegt ``itervalus`` nutzt, wenn über die Keys+ Values von nem ``dict``iteriert wird?
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.

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

cracki hat geschrieben:sape, du ueberzeugst mich...

Code: Alles auswählen

print [str(x) + 'spam' for x in test]
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.
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
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

<offtopic>
sape, da hab ich noch ne frage zu:
http://www.python-forum.de/post-55407.html#55407
</offtopic>
...meh...
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Doch, das kann man immer.

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].
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

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]
``map`` einspricht ``[f(x) for x in seq]``

:D
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

sape, es ist nun mal so wie birkenfeld sagt. LCs sind schneller als map/filter, sehen besser aus und du brauchst eigentlich nie ein lambda in einer LC.
...meh...
Antworten