Python中的lambda表达式中的赋值 [英] Assignment inside lambda expression in Python

查看:315
本文介绍了Python中的lambda表达式中的赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象列表,我想删除所有空的对象,除了一个,使用过滤器 lambda 表达式。

I have a list of objects and I want to remove all objects that are empty except for one, using filter and a lambda expression.

例如,如果输入是:

[Object(name=""), Object(name="fake_name"), Object(name="")]

...然后输出应该是:

...then the output should be:

[Object(name=""), Object(name="fake_name")]

有没有办法向 lambda 表达式添加一个作业?例如:

Is there a way to add an assignment to a lambda expression? For example:

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
)


推荐答案

您可以执行本地作业作为Python 2中列表推导的副作用。

You can perform local assignments as a side effect of list comprehensions in Python 2.

import sys
say_hello = lambda: [
    [None for message in ["Hello world"]],
    sys.stdout.write(message + "\n")
][-1]
say_hello()

,因为您的变量标志在外部范围内,而不是 lambda 的范围。这与 lambda 无关,这是Python 2中的一般行为。Python 3允许您使用 nonlocal 关键字里面的 def s,但是 nonlocal 不能在 lambda s和Python 3删除列表推导的这种副作用,所以这在Python 3中是不可能的。

However, it's not possible to use this in your example because your variable flag is in an outer scope, not the lambda's scope. This doesn't have to do with lambda, it's the general behaviour in Python 2. Python 3 lets you get around this with the nonlocal keyword inside of defs, but nonlocal can't be used inside lambdas and Python 3 removes this side effect of list comprehensions, so this isn't possible in Python 3.

有一个解决方法下面),但是当我们在这个主题...

There's a workaround (see below), but while we're on the topic...

在某些情况下,您可以使用它来做所有事情$ lambda

In some cases you can use this to do everything inside of a 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 cm³。

半径为20.0厘米,高度为40.0厘米的圆柱体积为50265.5厘米3。

半径为30.0厘米,高度为60.0的圆柱体厘米的体积为169646.0厘米3。

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³.

请不要。

...回到您的原始示例:虽然您不能对外部范围中的标志变量执行分配,您可以使用函数修改先前分配的值。

...back to your original example: though you can't perform assignments to the flag variable in the outer scope, you can use functions to modify the previously-assigned value.

例如,标志可以是一个对象, code> .value 我们使用 setattr设置

For example, flag could be an object whose .value we set using 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

If we wanted to fit the above theme, we could use a list comprehension instead of setattr:

    [None for flag.value in [bool(o.name)]]






但是,在严重的代码中,您应该始终使用常规函数定义而不是 lambda / $


But really, in serious code you should always use a regular function definition instead of a lambda if you're going to be doing assignment.

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中的lambda表达式中的赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆