Ich bin ein Python-Neuling, der versucht, Folgendes zu erreichen:
Ich habe eine Liste von Listen:
lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]
Ich möchte die Karte zuerst in eine andere Liste einfügen, die nur die zweitkleinste Zahl aus jeder Unterliste enthält. Das Ergebnis sollte also sein:
[345, 465, 333]
Wenn ich zum Beispiel nur an der kleinsten Zahl interessiert wäre, könnte ich Folgendes tun:
map(lambda x: min(x),lst)
Ich wünschte, ich könnte das tun:
map(lambda x: sort(x)[1],lst)
aber sortieren verkettet nicht. (gibt None zurück)
so etwas ist auch nicht erlaubt:
map(lambda x: sort(x); x[1],lst) #hence the multiple statement question
Gibt es eine Möglichkeit, dies mit Map in Python zu tun, ohne eine benannte Funktion zu definieren ? (Es ist zum Beispiel einfach mit anonymen Blöcken in Ruby)
lambda x: sort(x) OR x[1]
funktionieren würde: Hier wertet der OR sein erstes Argument (Rückgabewert None) als Bool (=> False) und in diesem Fall als OR aus gibt sein zweites Argument zurück. Aber wie die Antworten sagen, vermeiden Sie besser Lambda.Antworten:
Ich kann hier verschiedene Antworten geben, von Ihrer spezifischen Frage bis hin zu allgemeineren Anliegen. Also vom spezifischsten zum allgemeinsten:
Frage: Können Sie einem Lambda mehrere Aussagen hinzufügen?
A. Nein. Aber Sie brauchen eigentlich kein Lambda. Sie können die Anweisungen
def
stattdessen in ein setzen . dh:Frage: Können Sie das zweitniedrigste Element aus einem Lambda erhalten, indem Sie die Liste sortieren?
A. Ja. Wie die Antwort von alex zeigt,
sorted()
handelt es sich um eine Sortierversion, die eine neue Liste erstellt, anstatt sie direkt zu sortieren, und die verkettet werden kann. Beachten Sie, dass dies wahrscheinlich das ist, was Sie verwenden sollten - es ist eine schlechte Praxis, wenn Ihre Karte Nebenwirkungen auf die ursprüngliche Liste hat.Frage: Wie soll ich aus jeder Liste in einer Folge von Listen das zweitniedrigste Element erhalten?
A.
sorted(l)[1]
ist eigentlich nicht der beste Weg dafür. Es hat eine O (N log (N)) -Komplexität, während eine O (n) -Lösung existiert. Dies finden Sie im Heapq-Modul.Also benutze einfach:
Es wird normalerweise auch als klarer angesehen, ein Listenverständnis zu verwenden, das das Lambda insgesamt vermeidet:
quelle
k
(wie hier mit 'zweitniedrigste')O(k*log(n)+n)
vereinfacht sich zuO(n)
Das Einfügen der Anweisungen in eine Liste kann mehrere Anweisungen simulieren:
Z.B:
quelle
None
.Zeitreisender hier. Wenn Sie im Allgemeinen mehrere Anweisungen in einem Lambda haben möchten, können Sie diesem Lambda andere Lambdas als Argumente übergeben.
Sie können nicht mehrere Anweisungen haben, aber Sie können dies simulieren, indem Sie Lambdas an Lambdas übergeben.
Bearbeiten: Der Zeitreisende kehrt zurück! Sie können auch das Verhalten von Booleschen Ausdrücken (unter Berücksichtigung von Kurzschlussregeln und Wahrhaftigkeit) für Kettenoperationen missbrauchen. Mit dem ternären Operator erhalten Sie noch mehr Leistung. Auch hier können Sie nicht mehrere Anweisungen haben , aber Sie können natürlich viele Funktionsaufrufe haben. In diesem Beispiel wird beliebiger Junk mit einer Reihe von Daten ausgeführt, aber es zeigt, dass Sie einige lustige Dinge tun können. Die print-Anweisungen sind Beispiele für Funktionen, die
None
(wie auch die.sort()
Methode) zurückgegeben werden, aber sie helfen auch zu zeigen, was daslambda
tut.quelle
Verwenden Sie die sortierte Funktion wie folgt:
quelle
[sorted(x)[1] for x in list_of_lists]
.Sie können tatsächlich mehrere Anweisungen in einem Lambda-Ausdruck in Python haben. Es ist nicht ganz trivial, aber in Ihrem Beispiel funktioniert Folgendes:
Sie müssen sicherstellen, dass jede Anweisung nichts zurückgibt oder wenn sie es einschließt (.. und False). Das Ergebnis ist das, was von der letzten Bewertung zurückgegeben wird.
Beispiel:
quelle
Verwenden Sie begin () von hier aus: http://www.reddit.com/r/Python/comments/hms4z/ask_pyreddit_if_you_were_making_your_own/c1wycci
quelle
Eine hackige Möglichkeit, mehrere Anweisungen in Python zu einer einzigen Anweisung zu kombinieren, besteht darin, das Schlüsselwort "und" als Kurzschlussoperator zu verwenden. Dann können Sie diese einzelne Anweisung direkt als Teil des Lambda-Ausdrucks verwenden.
Dies ähnelt der Verwendung von "&&" als Kurzschlussoperator in Shell-Sprachen wie bash.
Beachten Sie auch: Sie können jederzeit eine Funktionsanweisung korrigieren, um einen wahren Wert zurückzugeben, indem Sie die Funktion einschließen.
Beispiel:
Beim zweiten Gedanken ist es wahrscheinlich besser, 'oder' anstelle von 'und' zu verwenden, da viele Funktionen bei Erfolg '0' oder Keine zurückgeben. Dann können Sie die Wrapper-Funktion im obigen Beispiel entfernen:
'und' operieren die Ausdrücke, bis der erste Null-Rückgabewert erreicht ist. Danach schließt es kurz. 1 und 1 und 0 und 1 ergibt: 1 und 1 und 0 und lässt 1 fallen
'oder' operiert die Ausdrücke, bis der erste Rückgabewert ungleich Null erreicht ist. Danach schließt es kurz.
0 oder 0 oder 1 oder 0 wertet 0 oder 0 oder 1 aus und lässt 0 fallen
quelle
Oder wenn Sie Lambda vermeiden und einen Generator anstelle einer Liste haben möchten:
(sortiert (col) [1] für col in lst)
quelle
Lassen Sie mich Ihnen einen herrlichen, aber schrecklichen Hack präsentieren:
Sie können dieses
LET
Formular jetzt als solches verwenden:was gibt:
[345, 465, 333]
quelle
Sie können dies in O (n) -Zeit mit min und index anstelle von sort oder heapq tun.
Erstellen Sie zuerst eine neue Liste von allem außer dem Mindestwert der ursprünglichen Liste:
Nehmen Sie dann den Mindestwert der neuen Liste:
Jetzt alles zusammen in einem einzigen Lambda:
Ja, es ist wirklich hässlich, aber es sollte algorithmisch billig sein. Auch da einige Leute in diesem Thread Listenverständnisse sehen wollen:
quelle
Genau dafür wird die
bind
Funktion in einer Monade verwendet.Mit der
bind
Funktion können Sie mehrere Lambdas zu einem Lambda kombinieren, wobei jedes Lambda eine Aussage darstellt.quelle
Es gibt tatsächlich eine Möglichkeit, mehrere Anweisungen in Lambda zu verwenden. Hier ist meine Lösung:
quelle
exec
kann nicht von einer intelligenten IDEJa. Sie können es auf diese Weise definieren und dann Ihre mehreren Ausdrücke wie folgt umschließen:
Schema beginnen:
begin = Lambda * x: x [-1]
Gemeinsame Lisp-Prognose:
Progn = Lambda * x: x [-1]
quelle
Es gibt bessere Lösungen ohne Lambda-Funktion. Wenn wir jedoch wirklich die Lambda-Funktion verwenden möchten, finden Sie hier eine generische Lösung für mehrere Anweisungen: map (Lambda x: x [1] if (x.sort ()) else x [1], lst)
Es ist dir egal, was die Anweisung zurückgibt.
quelle
Ja, es ist möglich. Versuchen Sie es mit dem folgenden Code-Snippet.
quelle
Ich gebe Ihnen eine andere Lösung: Lassen Sie Ihr Lambda eine Funktion aufrufen.
quelle
junky = multiple_statements
.