python:lambda、yield语句/表达式和循环(澄清)
TL;DR:我们能否在python:lambda、yield语句/表达式和循环(澄清),python,python-3.x,loops,lambda,generator,Python,Python 3.x,Loops,Lambda,Generator,TL;DR:我们能否在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 这看
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
这看起来像是,它期望某个东西作为未写入的返回语句的正确操作数,但发现yield
并感到困惑
是否有一个适当的合法的方法来实现这一点在一个循环
旁注:yield
可以是语句/表达式,具体取决于您询问的对象:
最终答案:产量可与lambda一起使用,但限制(单线)使其无效<代码>for/while在lambda中不可能,因为它们不是表达式-user2357112 implicit for循环可以通过列表理解实现,并且在列表理解中收益是有效的-懦夫
结论-显式循环不可能,因为python中的lambda只能包含表达式,要编写显式循环,需要使用语句-wim您试图创建的一个线性程序实际上在技术上是可以使用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只能包含,要编写显式循环,需要使用
如果您可以用生成器重写它,那么在
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
[1]中的x=(范围(15)中的i代表i)
In[2]:x
出[2]:
在[3]中:打印(*x)
Out[3]:011234576881011214
在[4]中:x=(i代表范围(0,15)中的i)
在[5]中:x.uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
Out[5]:0
在[6]中:下一个(x)
Out[6]:1
实际上,您可以通过有用的方式循环lambda,只是您提供的示例不是一个很好的用例
您可能希望在lambda
中使用yield
的一个实例可能是仅在需要时懒洋洋地执行昂贵的函数。像这样:
def昂贵的检查1():
打印(“昂贵支票1”)
返回真值
def昂贵_检查2():
打印(“昂贵支票2”)
返回真值
def昂贵_检查3():
打印(“昂贵支票3”)
返回真值
def do__thing(*args):
打印(args)
如果名称=“\uuuuu main\uuuuuuuu”:
为便于检查,请输入args(λ:(
(收益率(昂贵的支票1(),[“foo”,“bar”),
(收益率(昂贵的支票2(),[“baz”]),
(收益率(昂贵的支票3(),[]),
))():
如果检查:
做你想做的事(*args)
持续
引发异常(“哦,不!!!”)
其他:
打印(“一切正常!”)
输出:
expensive_check1
('foo', 'bar')
expensive_check2
('baz',)
expensive_check3
()
all OK!
请注意,昂贵的检查只发生在每个循环的开始,而不是一次完成。还请注意,此语法在Python 3.8+中仍然有效,因为它没有在理解中使用
yield
。“但是您也可以使用类似print()
的语句,只要它包含在一行中”-错误print
是Python 3中的一个函数,print
调用是普通表达式。不能在yield
调用中使用任意单行语句。尝试使用lambda
编写此语句毫无意义。如果您想将其填充到一行中,(范围(0,15)内的x代表x)
将是生成器函数的直接genexp翻译。我同意。我试图验证一个理论。再想一想,由于lambda
必须包含在单个语句中的限制,我怀疑在lambda
中有一个循环是否能实现任何目标。但最终澄清这一点会很好,因为它一直困扰着我。虽然从技术上讲,你可以在lambda函数中放入收益率
,但lambda函数的约束使得它基本上从来都不是一件有用的事情。你必须将(收益率x)
括起来。但是整个for
循环语法无论如何都不是一个有效的表达式。正如有人指出的,它基本上是一个发电机obj。您知道在/的同时是否可以使用进行此操作吗。另外,使用lambda单行代码也不能做任何事情。请注意,在Python2上的结果完全不同。这段代码以一种非常微妙的方式依赖于这样一个事实:在Python3上,列表理解是通过lambda
创建的匿名函数中的另一个匿名函数实现的。哇,这里发生了什么?你能解释一下[(收益率x)对范围(15)]
的作用吗?表达式返回什么?它返回一个生成器对象。当您迭代生成器时,您将获得在理解的迭代过程中生成的值。迭代完成后,StopIteration
异常实例将具有值
属性。这将是列表理解的结果:它将是一个长度为15的列表,此列表的元素将是发送到生成器中的项。您也可以执行类似的操作—它会惰性地计算每个函数,并且不会在3.8中被弃用:lamyield=lambda:((yield-private_-func1()),(yield-private_-func2()),(产生昂贵的函数3())