您可以在Python 2中执行本地分配作为列表推导的副作用。
import sys
say_hello = lambda: [
[None for message in ["Hello world"]],
sys.stdout.write(message + "\n")
][-1]
say_hello()
但是,在您的示例中不可能使用它,因为您的变量flag位于外部作用域中,而不是lambda的作用域。 这与lambda没有关系,它是Python 2中的一般行为.Python 3让你用.value里面的.value关键词来解决这个问题,但是nonlocal不能在lambdas里面使用,Python 3会删除这个副作用 列表推导,所以这在Python 3中是不可能的。
有一个解决方法(见下文),但我们正在谈论这个话题......
在某些情况下,您可以使用它来执行lambda内的所有操作:
(lambda: [
['def'
for sys in [__import__('sys')]
for math in [__import__('math')]
for sub in [lambda *vals: None]
for fun in [lambda *vals: vals[-1]]
for echo in [lambda *vals: sub(
sys.stdout.write(u" ".join(map(unicode, vals)) + u"\n"))]
for Cylinder in [type('Cylinder', (object,), dict(
__init__ = lambda self, radius, height: sub(
setattr(self, 'radius', radius),
setattr(self, 'height', height)),
volume = property(lambda self: fun(
['def' for top_area in [math.pi * self.radius ** 2]],
self.height * top_area))))]
for main in [lambda: sub(
['loop' for factor in [1, 2, 3] if sub(
['def'
for my_radius, my_height in [[10 * factor, 20 * factor]]
for my_cylinder in [Cylinder(my_radius, my_height)]],
echo(u"A cylinder with a radius of %.1fcm and a height "
u"of %.1fcm has a volume of %.1fcm³."
% (my_radius, my_height, my_cylinder.volume)))])]],
main()])()
半径为10.0厘米,高度为20.0厘米的圆柱体积为6283.2立方厘米。
半径20.0cm,高40.0cm的圆柱体积为50265.5cm³。
半径为30.0cm,高度为60.0cm的圆柱体积为169646.0cm³。
请不要。
...回到原始示例:虽然您无法对外部作用域中的lambda变量执行赋值,但您可以使用函数来修改先前指定的值。
例如,lambda可能是一个对象,其.value我们使用lambda设置:
flag = Object(value=True)
input = [Object(name=''), Object(name='fake_name'), Object(name='')]
output = filter(lambda o: [
flag.value or bool(o.name),
setattr(flag, 'value', flag.value and bool(o.name))
][0], input)
[Object(name=''), Object(name='fake_name')]
如果我们想要符合上述主题,我们可以使用列表理解而不是lambda:
[None for flag.value in [bool(o.name)]]
但实际上,在严格的代码中,如果您要进行分配,则应始终使用常规函数定义而不是lambda。
flag = Object(value=True)
def not_empty_except_first(o):
result = flag.value or bool(o.name)
flag.value = flag.value and bool(o.name)
return result
input = [Object(name=""), Object(name="fake_name"), Object(name="")]
output = filter(not_empty_except_first, input)