it-swarm.com.de

python: Lambda, Rendite-Anweisung/Ausdruck und Schleifen (Clarify)

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

13
theMobDog

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

16
wim

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.

1
Rick Teachey

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
0
N.C.