python - Python中的lambda表达式内的赋值

标签 python lambda expression variable-assignment

我有一个对象列表,我想使用 filterlambda 表达式删除除一个之外的所有空对象。

例如,如果输入是:

[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 中的一般行为。Python 3 允许您使用 def< 中的 nonlocal 关键字来解决这个问题s,但 nonlocal 不能在 lambdas 内使用。

有一个解决方法(见下文),但是当我们讨论这个主题时......


在某些情况下,您可以使用它来执行 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()])()

A cylinder with a radius of 10.0cm and a height of 20.0cm has a volume of 6283.2cm³.
A cylinder with a radius of 20.0cm and a height of 40.0cm has a volume of 50265.5cm³.
A cylinder with a radius of 30.0cm and a height of 60.0cm has a volume of 169646.0cm³.

请不要。


...回到你原来的例子:虽然你不能在外部范围内对 flag 变量执行赋值,但你可以使用函数来修改先前分配的值。

例如,flag 可以是我们使用 setattr 设置其 .value 的对象。 :

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/

相关文章:

python - 如何在 tensorflow 中提取层或 ValueError : Shape (? , 4096) 必须具有排名 1

无限循环内的 Raspberry Pi 用户输入中的 Python 在遇到许多输入时会丢失输入

node.js - Dynamodb batchWrite 无法在带有异步的 Lambda 中工作

java - 集合.forEach : How to add up values?

python - 如何获取树状图中节点下的所有叶子的列表?

python - (MNIST - GAN)第一次迭代后鉴别器和生成器误差下降到接近于零

c++ - 为什么不能捕获我的 C++ lambda 函数?

c# - EntityFramework - 选择具有自定义属性投影的实体

php - 用于解析带参数的方法的正则表达式

css - 使用类似 “input[class~=”的有效“&& type =“checkbox”]?