without - python tkinter lambda




Warum sind Python-Lambdas nützlich? (18)

Ich fange gerade mit Python an und rannte kopfüber nach Lambda - was mich eine Weile brauchte, um es herauszufinden.

Beachten Sie, dass dies keine Verurteilung von irgendetwas ist. Jeder hat andere Dinge, die nicht einfach sind.

Ist Lambda einer dieser "interessanten" Sprachartikel, die im wirklichen Leben vergessen werden sollten?

Nein.

Ich bin mir sicher, dass es einige Grenzfälle gibt, wo es nötig sein könnte, aber angesichts der Dunkelheit,

Es ist nicht obskur. Die letzten 2 Teams, an denen ich gearbeitet habe, nutzten diese Funktion die ganze Zeit.

das Potential, dass es in zukünftigen Releases neu definiert wird (meine Annahme basiert auf den verschiedenen Definitionen davon)

Ich habe keine ernsthaften Vorschläge gesehen, um es in Python neu zu definieren, nachdem ich vor ein paar Jahren noch die Semantik des Abschlusses festgelegt hatte.

und die reduzierte Codierungsklarheit - sollte es vermieden werden?

Es ist nicht weniger klar, wenn Sie es richtig verwenden. Im Gegenteil, mehr verfügbare Sprachkonstrukte erhöhen die Klarheit.

Das erinnert mich an Überlauf (Pufferüberlauf) von C-Typen - zeigt auf die oberste Variable und überladen, um die anderen Feldwerte zu setzen ... Art von Technik-Showman aber Wartung Coder Albtraum ..

Lambda ist wie Pufferüberlauf? Beeindruckend. Ich kann mir nicht vorstellen, wie Sie Lambda verwenden, wenn Sie denken, dass es ein "Wartungs-Albtraum" ist.

Ich versuche herauszufinden, Python Lambdas. Ist Lambda einer jener "interessanten" Sprachartikel, die im wirklichen Leben vergessen werden sollten?

Ich bin mir sicher, dass es einige Randfälle gibt, in denen es nötig sein könnte, aber angesichts der Unklarheit dessen, das Potenzial, dass es in zukünftigen Versionen neu definiert wird (meine Annahme basiert auf den verschiedenen Definitionen davon) und die reduzierte Codierungsklarheit - sollte es Gemieden werden?

Das erinnert mich an einen Überlauf (Pufferüberlauf) von C-Typen, der auf die oberste Variable zeigt und die anderen Feldwerte überlädt. Es fühlt sich an wie ein Techie-Showmanship, aber ein Coder-Albtraum.


Die zweizeilige Zusammenfassung:

  1. Closures : Sehr nützlich. Lerne sie, benutze sie, liebe sie.
  2. Pythons lambda Schlüsselwort: unnötig, gelegentlich nützlich. Wenn Sie feststellen, dass Sie irgendetwas entfernt komplexes damit tun, legen Sie es weg und definieren Sie eine echte Funktion.

Eine der netten Sachen über lambda , die meiner Meinung nach untertrieben ist, ist, dass es eine Möglichkeit ist, eine Bewertung für einfache Formulare zu verschieben, bis der Wert benötigt wird. Lassen Sie mich erklären.

Viele Bibliotheksroutinen sind so implementiert, dass sie bestimmte Parameter als Callables zulassen (von denen Lambda eins ist). Die Idee ist, dass der tatsächliche Wert nur zu dem Zeitpunkt berechnet wird, zu dem er verwendet wird (eher als wenn er aufgerufen wird). Ein (erfundenes) Beispiel könnte helfen, den Punkt zu veranschaulichen. Angenommen, Sie haben eine Routine, die einen bestimmten Zeitstempel protokolliert. Sie möchten, dass die Routine die aktuelle Zeit minus 30 Minuten verwendet. Du würdest es so nennen

log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30))

Angenommen, die tatsächliche Funktion wird nur aufgerufen, wenn ein bestimmtes Ereignis eintritt und der Zeitstempel nur zu diesem Zeitpunkt berechnet werden soll. Sie können das so machen

log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30))

Angenommen, der log_timestamp kann log_timestamp wie diesen behandeln, wird er dies bei Bedarf auswerten und Sie erhalten den Zeitstempel zu diesem Zeitpunkt.

Es gibt natürlich alternative Möglichkeiten, dies zu tun (zum Beispiel mit dem operator Modul), aber ich hoffe, ich habe den Punkt vermittelt.

Update : Here ist ein etwas konkreteres Beispiel aus der realen Welt.

Update 2 : Ich denke, dies ist ein Beispiel dafür, was ein thunk .


Erste Gratulation, dass es gelungen ist, Lambda herauszufinden. Meiner Meinung nach ist dies ein wirklich mächtiges Konstrukt, um damit zu handeln. Der Trend hin zu funktionalen Programmiersprachen ist sicherlich ein Indikator dafür, dass er weder vermieden werden sollte noch in naher Zukunft neu definiert wird.

Du musst nur ein bisschen anders denken. Ich bin mir sicher, bald wirst du es lieben. Aber sei vorsichtig, wenn du nur mit Python arbeitest. Weil das Lambda kein echter Verschluss ist, ist es irgendwie "gebrochen": Pythons Lambda ist gebrochen


Ich bezweifle, dass Lambda weggehen wird. Sieh Guido's Post darüber, endlich aufzugeben, es zu entfernen. Siehe auch einen Überblick über den Konflikt .

Sie können diesen Beitrag für mehr eine Geschichte über den Deal hinter Pythons funktionalen Funktionen http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html : http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

Kurioserweise wurden die Funktionen zum Zuordnen, Filtern und Reduzieren, die ursprünglich die Einführung von Lambda und anderen funktionalen Merkmalen motiviert hatten, zu einem großen Teil durch Listenerläuterungen und Generatorausdrücke ersetzt. Tatsächlich wurde die Reduce-Funktion aus der Liste der eingebauten Funktionen in Python 3.0 entfernt. (Es ist jedoch nicht notwendig, Beschwerden über die Entfernung von Lambda, Karte oder Filter zu senden: sie bleiben. :-)

Meine eigenen zwei Cent: Selten ist Lambda es wert, soweit es die Klarheit geht. Im Allgemeinen gibt es eine klarere Lösung, die Lambda nicht enthält.


Ich finde Lambda nützlich für eine Liste von Funktionen, die das gleiche tun, aber für verschiedene Umstände. Wie die Mozilla Pluralregeln .

plural_rules = [
    lambda n: 'all',
    lambda n: 'singular' if n == 1 else 'plural',
    lambda n: 'singular' if 0 <= n <= 1 else 'plural',
    ...
]
# Call plural rule #1 with argument 4 to find out which sentence form to use.
plural_rule[1](4) # returns 'plural'

Wenn Sie für alle eine Funktion definieren müssten, würden Sie am Ende verrückt werden. Es wäre auch nicht nett mit Funktionsnamen wie plural_rule_1 , plural_rule_2 , etc. Und Sie müssten es eval() , wenn Sie auf eine Variable Funktion ID plural_rule_2 sind.


Ich kann nicht mit Pythons spezieller Implementierung von Lambda sprechen, aber im Allgemeinen sind Lambda-Funktionen wirklich praktisch. Sie sind eine Kerntechnik (vielleicht sogar DIE Technik) der funktionalen Programmierung, und sie sind auch sehr nützlich in objektorientierten Programmen. Für bestimmte Arten von Problemen sind sie die beste Lösung, also sollte nicht vergessen werden!

Ich schlage vor, dass Sie die Closures und die map-Funktion (die auf Python-Dokumente verweist, aber in fast jeder Sprache existiert, die funktionale Konstrukte unterstützt) nachlesen können, um zu sehen, warum sie nützlich ist.


In Python ist lambda nur eine Möglichkeit, Funktionen inline zu definieren,

a = lambda x: x + 1
print a(1)

und..

def a(x): return x + 1
print a(1)

.. sind genau die gleichen.

Es gibt nichts, was man mit Lambda machen kann, was man mit einer regulären Funktion nicht tun kann - in Python-Funktionen ist ein Objekt genau wie alles andere, und Lambdas definieren einfach eine Funktion:

>>> a = lambda x: x + 1
>>> type(a)
<type 'function'>

Ich glaube wirklich, dass das lambda Schlüsselwort in Python redundant ist - ich hatte nie die Notwendigkeit, sie zu verwenden (oder gesehen, wo eine reguläre Funktion, ein Listenverständnis oder eine der vielen eingebauten Funktionen besser hätte verwendet werden können).

Für ein völlig zufälliges Beispiel, aus dem Artikel "Pythons Lambda ist kaputt!" :

Um zu sehen, wie Lambda gebrochen ist, versuche, eine Liste von Funktionen zu erzeugen fs=[f0,...,f9] wobei fi(n)=i+n . Erster Versuch:

>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13

Ich würde argumentieren, auch wenn das funktionieren würde, es ist schrecklich und "unpythonisch", die gleiche Funktionalität könnte auf unzählige andere Arten geschrieben werden, zum Beispiel:

>>> n = 4
>>> [i + n for i in range(10)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

Ja, es ist nicht das Gleiche, aber ich habe noch nie eine Ursache gesehen, wo eine Gruppe von Lambda-Funktionen in einer Liste erzeugt werden muss. Es könnte in anderen Sprachen sinnvoll sein, aber Python ist nicht Haskell (oder Lisp oder ...)

Bitte beachten Sie, dass wir Lambda verwenden können und trotzdem auf diese Weise die gewünschten Ergebnisse erzielen:

>>> fs = [(lambda n,i=i: i + n) for i in range(10)]
>>> fs[3](4)
7

Bearbeiten:

Es gibt ein paar Fälle, in denen Lambda nützlich ist, zum Beispiel ist es oft praktisch, wenn Signale in PyQt-Anwendungen wie folgt verbunden werden:

w = PyQt4.QtGui.QLineEdit()
w.textChanged.connect(lambda event: dothing())

w.textChanged.connect(dothing) dothing Methode dothing mit einem zusätzlichen event dothing und ein Fehler verursacht. Mit den Lambda-Mitteln können wir das Argument sauber löschen, ohne eine Umbruchfunktion definieren zu müssen.


Lambdas sind im Allgemeinen tief mit dem funktionalen Programmierstil verbunden. Die Idee, dass Sie Probleme lösen können, indem Sie eine Funktion auf einige Daten anwenden und die Ergebnisse zusammenführen, verwendet Google, um die meisten seiner Algorithmen zu implementieren.

Programme, die in einem funktionalen Programmierstil geschrieben sind, können leicht parallelisiert werden und werden daher mit modernen Mehrkern-Maschinen immer wichtiger. Kurz gesagt, NEIN sollten Sie sie nicht vergessen.


Lambdas sind tatsächlich sehr mächtige Konstrukte, die aus Ideen in der funktionalen Programmierung stammen, und es ist etwas, das in naher Zukunft von Python auf keinen Fall einfach überarbeitet, neu definiert oder entfernt werden wird. Sie helfen Ihnen, Code zu schreiben, der leistungsfähiger ist, da Sie Funktionen als Parameter weitergeben können, also die Idee von Funktionen als erstklassige Bürger.

Lambdas tendieren dazu, verwirrend zu werden, aber sobald ein solides Verständnis erreicht ist, kannst du sauberen, eleganten Code wie diesen schreiben:

squared = map(lambda x: x*x, [1, 2, 3, 4, 5])

Die obige Codezeile gibt eine Liste der Quadrate der Zahlen in der Liste zurück. Natürlich könntest du es auch so machen:

def square(x):
    return x*x

squared = map(square, [1, 2, 3, 4, 5])

Es ist offensichtlich, dass der frühere Code kürzer ist, und dies gilt insbesondere, wenn Sie die Map-Funktion (oder eine ähnliche Funktion, die eine Funktion als Parameter akzeptiert) nur an einer Stelle verwenden möchten. Dies macht den Code auch intuitiver und eleganter.

Auch, wie David Zaslavsky in seiner Antwort erwähnt hat, sind Listenkompromittierungen nicht immer der richtige Weg, besonders wenn Ihre Liste Werte von einem obskuren mathematischen Weg erhalten muss.

Aus praktischer Sicht war einer der größten Vorteile von Lambdas für mich in letzter Zeit die GUI- und ereignisgesteuerte Programmierung. Wenn Sie Rückrufe in Tkinter betrachten, nehmen sie als Argumente nur das Ereignis an, das sie ausgelöst hat. Z.B

def define_bindings(widget):
    widget.bind("<Button-1>", do-something-cool)

def do-something-cool(event):
    #Your code to execute on the event trigger

Was wäre, wenn Sie einige Argumente hätten, die bestanden werden? Etwas so einfaches wie das Übergeben von 2 Argumenten zum Speichern der Koordinaten eines Mausklicks. Du kannst es leicht so machen:

def main():
    # define widgets and other imp stuff
    x, y = None, None
    widget.bind("<Button-1>", lambda event: do-something-cool(x, y))

def do-something-cool(event, x, y):
    x = event.x
    y = event.y
    #Do other cool stuff

Jetzt können Sie argumentieren, dass dies mit globalen Variablen getan werden kann, aber wollen Sie sich wirklich den Kopf schütteln, wenn Sie sich Gedanken über die Speicherverwaltung und das Leaking machen, besonders wenn die globale Variable nur an einem bestimmten Ort verwendet wird? Das wäre nur ein schlechter Programmierstil.

Kurz gesagt, Lambdas sind fantastisch und sollten nie unterschätzt werden. Python-Lambdas sind zwar nicht die gleichen wie LISP-Lambdas (die mächtiger sind), aber man kann wirklich eine Menge magischer Dinge mit ihnen machen.


Sprechen Sie über Lambda-Funktionen ? Mögen

lambda x: x**2 + 2*x - 5

Diese Dinge sind tatsächlich ziemlich nützlich. Python unterstützt einen Programmierstil namens funktionale Programmierung, bei dem Sie Funktionen an andere Funktionen übergeben können. Beispiel:

mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])

setzt mult3 auf [3, 6, 9] , jene Elemente der ursprünglichen Liste, die Vielfache von 3 sind. Das ist kürzer (und man könnte argumentieren, klarer) als

def filterfunc(x):
    return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])

Natürlich könnten Sie in diesem speziellen Fall dasselbe wie ein Listenverständnis tun:

mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]

(oder sogar als range(3,10,3) , range(3,10,3) , range(3,10,3) ), aber es gibt viele andere, anspruchsvollere Anwendungsfälle, in denen Sie kein Listenverständnis verwenden können und eine Lambda-Funktion der kürzeste Weg sein kann, etwas zu schreiben.

  • Rückgabe einer Funktion von einer anderen Funktion

    >>> def transform(n):
    ...     return lambda x: x + n
    ...
    >>> f = transform(3)
    >>> f(4)
    7
    

    Dies wird oft verwendet, um Funktionswrapper zu erstellen, z. B. Pythons Dekoratoren.

  • Elemente einer iterierbaren Sequenz mit reduce() kombinieren

    >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])
    '1, 2, 3, 4, 5, 6, 7, 8, 9'
    
  • Sortieren nach einem alternativen Schlüssel

    >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
    [5, 4, 6, 3, 7, 2, 8, 1, 9]
    

Ich benutze Lambda-Funktionen regelmäßig. Es hat eine Weile gedauert, mich an sie zu gewöhnen, aber irgendwann habe ich verstanden, dass sie ein sehr wertvoller Teil der Sprache sind.


Wie oben erwähnt, definiert der Lambda-Operator in Python eine anonyme Funktion, und in Python-Funktionen sind Closures. Es ist wichtig, das Konzept der Verschlüsse nicht mit dem Operator Lambda zu verwechseln, bei dem es sich lediglich um syntaktisches Methadon handelt.

Als ich vor ein paar Jahren in Python angefangen habe, habe ich sehr viel lambdas benutzt und dachte, dass sie cool sind, zusammen mit List Comprehensions. Ich schrieb und muss jedoch eine große Website in Python in der Größenordnung von mehreren tausend Funktionspunkten pflegen. Ich habe aus Erfahrung gelernt, dass Lambdas in Ordnung sein können, um Dinge zu prototypieren, aber nichts über Inline-Funktionen (sogenannte Closures) bieten, außer dass man ein paar Key-Stokes speichert oder manchmal nicht.

Grundsätzlich läuft das auf mehrere Punkte hinaus:

  • Es ist einfacher, Software zu lesen, die explizit mit aussagekräftigen Namen geschrieben wurde. Anonyme Verschlüsse können definitionsgemäß keinen aussagekräftigen Namen haben, da sie keinen Namen haben. Diese Kürze scheint aus irgendeinem Grund auch Lambda-Parameter zu infizieren, daher sehen wir oft Beispiele wie Lambda x: x + 1
  • Es ist einfacher, Named-Closures wiederzuverwenden, da sie mehr als einmal mit Namen bezeichnet werden können, wenn es einen Namen gibt, auf den sie verweisen.
  • Es ist einfacher, Code zu debuggen, der named closures anstelle von lambdas verwendet, da der Name in tracebacks und um den Fehler herum angezeigt wird.

Das ist Grund genug, sie zusammenzufassen und in Namensschließungen umzuwandeln. Ich halte jedoch zwei weitere Groll gegen anonyme Schließungen.

Der erste Groll ist einfach, dass sie nur ein weiteres unnötiges Schlüsselwort sind, das die Sprache verstopft.

Der zweite Groll ist tiefer und auf Paradigma-Ebene, dh ich mag es nicht, dass sie einen funktionalen Programmierstil fördern, weil dieser Stil weniger flexibel ist als der Nachrichtenübergabe-, objektorientierte oder prozedurale Stil, weil der Lambda-Kalkül nicht Turing- ist. vollständig (zum Glück können wir in Python diese Einschränkung sogar innerhalb eines Lambda ausbrechen). Die Gründe, warum ich lambdas für diesen Stil halte, sind:

  • Es gibt eine implizite Rückkehr, dh sie scheinen so zu sein, als ob sie Funktionen wären.

  • Sie sind ein alternativer Mechanismus zum Verbergen von Zuständen zu einem anderen, expliziteren, besser lesbaren, wiederverwendbaren und allgemeineren Mechanismus: Methoden.

Ich bemühe mich, lambda-freies Python zu schreiben und lambdas auf Sicht zu entfernen. Ich denke Python wäre eine etwas bessere Sprache ohne Lambdas, aber das ist nur meine Meinung.


Lambda-Funktion ist es eine unbürokratische Möglichkeit, eine Funktion zu erstellen.

Das ist es. Nehmen wir zum Beispiel an, Sie haben Ihre Hauptfunktion und müssen Werte quadrieren. Lass uns den traditionellen Weg und den Lambda-Weg sehen, dies zu tun:

Traditioneller Weg:

def main():
...
...
y = square(some_number)
...
return something

def square(x):
    return x**2

Der Lambda-Weg:

def main():
...
square = lambda x: x**2
y = square(some_number)
return something

Sieh den Unterschied?

Lambda-Funktionen passen sehr gut zu Listen, wie Listen Comprehensions oder Map. In der Tat, Listenverständnis ist es eine "pythonische" Möglichkeit, sich mit Lambda auszudrücken. Ex:

>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]

Mal sehen, was jedes Element der Syntax bedeutet:

[]: "Gib mir eine Liste"

x ** 2: "Verwenden dieser neuen Funktion"

für x in a: "in jedes Element in einem"

Das ist bequem, äh? Funktionen wie diese erstellen. Lass es uns mit Lambda umschreiben:

>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]

Jetzt benutzen wir map, was dasselbe ist, aber sprachneutraler. Maps benötigt 2 Argumente:

(i) eine Funktion

(ii) ein iterierbares

Und gibt Ihnen eine Liste, in der jedes Element die Funktion ist, die auf jedes Element des Iterablen angewendet wird.

Also, mit der Karte hätten wir:

>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)

Wenn Sie lambdas und Mapping beherrschen, haben Sie eine große Macht, Daten zu manipulieren. Lambda-Funktionen sind weder obskur noch entziehen sie der Code-Klarheit. Verwechsle nicht etwas Hartes mit etwas Neuem. Sobald Sie anfangen, sie zu benutzen, werden Sie es sehr klar finden.


A useful case for using lambdas is to improve the readability of long list comprehensions . In this example loop_dic is short for clarity but imagine loop_dic being very long. If you would just use a plain value that includes i instead of the lambda version of that value you would get a NameError .

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

Anstatt von

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

I use lambda to create callbacks that include parameters. It's cleaner writing a lambda in one line than to write a method to perform the same functionality.

Beispielsweise:

import imported.module

def func():
    return lambda: imported.module.method("foo", "bar")

as opposed to:

import imported.module

def func():
    def cb():
        return imported.module.method("foo", "bar")
    return cb

I use it quite often, mainly as a null object or to partially bind parameters to a function.

Here are examples:

to implement null object pattern:

{
    DATA_PACKET: self.handle_data_packets
    NET_PACKET: self.handle_hardware_packets
}.get(packet_type, lambda x : None)(payload)

for parameter binding:

let say that I have the following API

def dump_hex(file, var)
    # some code
    pass

class X(object):
    #...
    def packet_received(data):
        # some kind of preprocessing
        self.callback(data)
    #...

Then, when I wan't to quickly dump the recieved data to a file I do that:

dump_file = file('hex_dump.txt','w')
X.callback = lambda (x): dump_hex(dump_file, x)
...
dump_file.close()

I'm a python beginner, so to getter a clear idea of lambda I compared it with a 'for' loop; in terms of efficiency. Here's the code (python 2.7) -

import time
start = time.time() # Measure the time taken for execution

def first():
    squares = map(lambda x: x**2, range(10))
    # ^ Lambda
    end = time.time()
    elapsed = end - start
    print elapsed + ' seconds'
    return elapsed # gives 0.0 seconds

def second():
    lst = []
    for i in range(10):
        lst.append(i**2)
    # ^ a 'for' loop
    end = time.time()
    elapsed = end - start
    print elapsed + ' seconds'
    return elapsed # gives 0.0019998550415 seconds.

print abs(second() - first()) # Gives 0.0019998550415 seconds!(duh)

Lambda is a procedure constructor. You can synthesize programs at run-time, although Python's lambda is not very powerful. Note that few people understand that kind of programming.





closures