TLDR:
Können wir yield
oder eine Generatoranweisung (mit einer Schleife) innerhalb einer lambda
implementieren?
Meine Frage ist zu klären:
Ob die folgende einfache Schleifenfunktion mit Ausbeute implementiert werden kann
def loopyield():
for x in range(0,15):
yield x
print(*loopyield())
Ergebnisse im Fehler:
lamyield=lambda x: yield x for x in range(0,15)
^
SyntaxError: invalid syntax
Wie es aussieht, erwartete es etwas als rechten Operanden für eine ungeschriebene return-Anweisung, fand jedoch die yeild
und wurde verwirrt.
Gibt es einen richtigen Weg, um dies in einer Schleife zu erreichen?
Randbemerkung: yield
kann Anweisung/Ausdruck sein, je nachdem, wen Sie fragen: Ertrag - Anweisung oder Ausdruck?
Letzte Antwort: ertrag kann mit Lambda verwendet werden, aber die Einschränkung (einzeilig) macht es unbrauchbar. for/while
ist in Lambda nicht möglich, da sie keine Ausdrücke sind. -user2357112 implizit für Schleife ist mit Listenverständnis möglich, und die Ausbeute ist innerhalb des Listenverständnisses gültig. -wim
Verdict- Explizite Schleifen sind nicht möglich, da Lambdas in Python nur Ausdrücke enthalten können. Um eine explizite Schleife zu schreiben, müssen Sie Anweisungen verwenden. -wim
Der Ein-Liner, den Sie zu schaffen scheinen, ist mit einem Lambda eigentlich technisch möglich, Sie müssen dem Parser nur ein wenig mehr helfen:
>>> lamyield = lambda: [(yield x) for x in range(15)]
>>> print(*lamyield())
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Hierbei wird implizit eine for-Schleife in einem Listenverständnis verwendet. Mit einer expliziten while
-Schleife oder for
-Schleife außerhalb eines Verständnisses ist dies nicht möglich. Das liegt daran, dass Lambdas in Python nur Ausdrücke enthalten können. Um eine explizite Schleife zu schreiben, müssen Sie Anweisungen verwenden.
Hinweis: Diese Syntax ist in Python 3.7 veraltet und erhöht SyntaxError
in Python 3.8
Sie können ein Lambda tatsächlich auf nützliche Weise durchlaufen, nur dass das von Ihnen bereitgestellte Beispiel kein großartiger Anwendungsfall ist.
Eine Möglichkeit, in der Sie yield
in einem lambda
verwenden möchten, besteht darin, teure Funktionen nur bei Bedarf faul auszuführen. Wie so:
for check, args in (lambda: (
(yield (expensive_check1(), ["foo", "bar"])),
(yield (expensive_check2(), ["baz"])),
(yield (expensive_check3(), []), [])),
))():
if check:
x = do_the_thing(*args)
break
else:
raise Exception("oh noes!!!")
* Beachten Sie, dass diese Syntax in Python 3.8) weiterhin funktioniert, da das yield
nicht in einem Verständnis verwendet wird.
Ist es notwendig, yeild
in lambda
zu verwenden, wenn Sie es mit Generator so umschreiben können?
In[1]: x = (i for i in range(15))
In[2]: x
Out[2]: <generator object <genexpr> at 0x7fbdc69c3f10>
In[3]: *x
Out[3]: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
In[4]: x = (i for i in range(0, 15))
In[5]: x.__next__()
Out[5]: 0
In[6]: next(x)
Out[6]: 1