python:lambda,yield语句/表达式和循环(Clarify)

2024-03-28 15:25:21 发布

您现在位置:Python中文网/ 问答频道 /正文

TLDR:我们可以在lambda内实现yield或生成器语句(带循环)吗?

我的问题是澄清:

下面的简单循环函数是否可以用yield实现

def loopyield():
   for x in range(0,15):
      yield x
print(*loopyield())

导致错误:

lamyield=lambda x: yield x for x in range(0,15)
                       ^
SyntaxError: invalid syntax

这看起来像是,它希望某个操作数是未写入的返回语句的正确操作数,但却发现yeild并感到困惑。

有没有一个正确的合法方法来实现这个循环?

旁注:yield可以是语句/表达式,具体取决于您问谁:yield - statement or expression?

最终答案:产量可以与lambda一起使用,但限制(单行)使其无用。for/while在lambda中不可能,因为它们不是表达式。-user2357112隐式for循环在列表理解中是可能的,而yield在列表理解中是有效的。-wim

结论-显式循环不可能,因为python中的lambda只能包含表达式,要编写显式循环,您需要使用语句。-wim


Tags: lambda函数in列表for表达式def错误
3条回答

实际上,您可以以有用的方式循环lambda,只是您提供的示例不是一个很好的用例。

您可能希望在lambda中使用yield的一个实例可能是仅在需要时才惰性地执行昂贵的函数。就像这样:

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!!!")

*注意,这个语法在Python3.8中仍然有效,因为它没有在理解中使用yield

如果您可以用生成器重写lambda内部的yield是否有必要?

In[1]: x = (i for i in range(15))
In[2]: x
Out[2]: <generator object <genexpr> at 0x7fbdc69c3f10>

In[3]: print(*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

在lambda中,您试图创建的一行代码实际上在技术上是可行的,您只需要进一步帮助解析器:

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

这在列表理解中隐式地使用for循环。在理解之外使用显式的while循环或for循环是不可能的。这是因为python中的lambdas只能包含expressions,要编写显式循环,需要使用statements

Note: this syntax is deprecated in Python 3.7, and will raise ^{} in Python 3.8

相关问题 更多 >