python:lambda,yield-statement / expression和loops(Clarify)

时间:2016-11-14 17:45:24

标签: python python-3.x loops lambda generator

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

我的问题是澄清:

是否可以使用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中的lambdas只能包含表达式,要编写显式循环,您需要使用语句。 -wim

3 个答案:

答案 0 :(得分:22)

您似乎尝试创建的单行实际上在技术上可以使用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 SyntaxError in Python 3.8

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

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

*请注意,此语法在Python 3.8中仍然适用,因为它没有在理解内使用yield