提问人:datapy 提问时间:10/12/2023 更新时间:10/12/2023 访问量:60
是否可以在 Python Lambda 函数中使用非本地函数?
is it possible to have nonlocal in python lambda function?
问:
现在我的 lambda 函数是:
In [40]: f=lambda x, count=0: count if not(x%3==0) else count+1
In [41]: [f(x) for x in range(10)]
Out[41]: [1, 0, 0, 1, 0, 0, 1, 0, 0, 1]
但我真正想要的是累积计数,以便输出为:
Out[42]: [1, 1, 1, 2, 2, 2, 3, 3, 3, 4]
我正在寻找一些代码,例如:
f=lambda x, count=0: nonlocal count if not(x%3==0) else count+1
但收到使用“nonlocal”的语法错误消息。所以我的问题是:有没有办法在 lambda 中定义非局部变量?
答:
2赞
juanpa.arrivillaga
10/12/2023
#1
通常,lambda 函数应该是纯函数,这就是为什么它们被故意限制为表达式的原因。
因此,您不能在 lambda 表达式中赋值给非局部/全局变量(尽管您可以使用赋值表达式赋值给局部变量)。
如果要使用 / 并赋值给变量,则始终只能使用函数定义语句。您永远不必使用 lambda 表达式来创建函数。lambda 表达式的功能受到有意限制。如果您想要更多的东西,只需使用函数定义语句即可。nonlocal
global
但在这种情况下,你不应该这样做 在这种情况下,你正在尝试使用列表推导来产生副作用。这通常令人困惑,并被认为是一种反模式。最好直接使用 for 循环:
result = []
count = 0
for i in range(10):
if i%3 == 0:
count += 1
result.append(count)
这是完美的pythonic。
但是,如果您想要一种更实用的编程方法,则应使用:itertools.accumulate
import itertools
result = itertools.accumulate(map(lambda x: int(x%3 == 0), range(10)))
Lambda 表达式不能包含类似 或 的语句。但是您应该为这项工作选择正确的工具,在这种情况下,它要么只是一个普通的 for 循环,要么 .nonlocal
global
itertools.accumualte
0赞
skxxtz
10/12/2023
#2
如果您确实必须使用 lambda 函数来执行此操作,您可以尝试以下操作:
count = 0
f = lambda x: (setattr(f, 'count', getattr(f, 'count', 0) + 1) if x % 3 == 0 else None, f.count)[1]
print([f(x) for x in range(10)])
不过,我建议再次这样做。这些家伙给了你一些比 lambda 更好的选择......
评论
global
nonlocal
def
nonlocal
[(x // 3 )+ 1 for x in range(10)]