我有一个对象列表,我想使用filter
和lambda
表达式删除除一个以外的所有空对象。
例如,如果输入是:
[Object(name=""), Object(name="fake_name"), Object(name="")]
...那么输出应为:
[Object(name=""), Object(name="fake_name")]
有没有一种方法可以向
lambda
表达式添加赋值?例如:flag = True
input = [Object(name=""), Object(name="fake_name"), Object(name="")]
output = filter(
(lambda o: [flag or bool(o.name), flag = flag and bool(o.name)][0]),
input
)
最佳答案
The assignment expression operator :=
added in Python 3.8支持lambda表达式内部的赋值。出于语法原因,此运算符只能出现在带括号的(...)
,方括号[...]
或大括号{...}
表达式内。例如,我们将能够编写以下内容:
import sys
say_hello = lambda: (
message := "Hello world",
sys.stdout.write(message + "\n")
)[-1]
say_hello()
在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中的常规行为。Python3使您可以在nonlocal
s内使用def
关键字解决此问题,但是nonlocal
不能在lambda
s中使用。有一种解决方法(请参见下文),但是当我们讨论该主题时...
在某些情况下,您可以使用它来完成
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()])()
请不要
...回到原始示例:尽管您无法在外部范围内对
flag
变量进行赋值,但是可以使用函数来修改先前分配的值。例如,
flag
可以是我们使用 .value
设置其setattr
的对象: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')]
如果我们想适合上述主题,可以使用列表推导代替
setattr
: [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)
关于python - Python中Lambda表达式内的赋值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6282042/