【问题标题】:a strange usage for lambda in python [duplicate]python中lambda的一个奇怪用法[重复]
【发布时间】:2021-02-18 18:32:01
【问题描述】:

遇到一段代码如下,其中workers是类对象的列表:

worker_threads = []
for worker in workers:
    worker_fn = lambda worker=worker: worker.run(sess, coord, FLAGS.t_max)
    t = threading.Thread(target=worker_fn)
    t.start()
    worker_threads.append(t)

通常我希望lambda 的语法是lambda x : func(x),但这里的worker=worker 用于什么?

【问题讨论】:

  • 它是否有效或是否会导致错误?
  • 我相信它就像函数中的任何其他参数一样工作,它将 for 循环 worker 设置为 lambda 表达式的默认值
  • 它将 lambda 中的 worker 的值绑定到执行 lambda 时的值。如果你不这样做,worker 的值将随着for 循环的迭代在所有 lambda 中发生变化。
  • 让我看看我能不能想出一个最小的例子作为一个实际的答案......

标签: python lambda


【解决方案1】:

worker 的值绑定到 lambda 中。这是该技术的一个简化示例:

>>> thunks = [lambda: i for i in range(5)]
>>> [thunk() for thunk in thunks]
[4, 4, 4, 4, 4]
>>>
>>> thunks = [lambda i=i: i for i in range(5)]
>>> [thunk() for thunk in thunks]
[0, 1, 2, 3, 4]

使用表达式lambda: ii调用 lambda 时计算,而不是在定义 时计算。因此,在第一个示例中,所有 thunk 的结果都是 4,因为这是 irange(5) 循环结束时的值。

使用表达式lambda i=i: i,现在i 的值在循环内被立即评估,以提供i 参数的默认值。这允许每个 thunk 捕获 i 的唯一值。

如果参数被赋予不同的名称而不是阴影i,这个概念可能会更清晰:

>>> thunks = [lambda n=i: n for i in range(5)]
>>> [thunk() for thunk in thunks]
[0, 1, 2, 3, 4]

在您的示例中,lambda 可以写为:

worker_fn = lambda w=worker: w.run(sess, coord, FLAGS.t_max)

这与代码中的worker=worker: worker.run... 表达式的行为相同,但可能更清楚一点,表达式的目的是在循环中获取worker 的当前值并将其传递到主体的 lambda 作为参数。

【讨论】:

  • 可能需要指出的是,这种行为并非特定于 lambda 表达式,所有函数都以这种方式工作
【解决方案2】:

不是答案,但这有效:

t = list()
for i in [1,2,3,4]:
  func = lambda x=i: x*x
  t.append(func)

print(t[1]) 
# <function <lambda> at 0x7fdba6e6d790>
print(t[1]()) 
# 4

因此您可以将变量/参数绑定到 lambda 函数

说明here

【讨论】:

    【解决方案3】:

    这样想:

    def f(x):
        print(x)
    
    f('yes')
    
    >>> 'yes'
    
    x = 'no'
    def f(x=x):
        print(x)
    
    f()
    >>> 'no'
    
    f('yes')
    >>> 'yes'
    

    或者在 lambda 世界中:

    
    f = lambda x:print(x)
    
    f('yes')
    
    >>> 'yes'
    
    x = 'no'
    f = lambda x=x: print(x)
    
    f()
    >>> 'no'
    
    f('yes')
    >>> 'yes'
    
    

    因此,为了让这里的评论者明确回答 WHY,这样做可以让每个 lambda 定义一个不同的默认 x 值。

    【讨论】:

    • 你的答案与 lambda 无关
    • 问题是问为什么要使用它,答案最容易用标准函数 imo 解释
    • 这实际上并不能解释为什么它发生在 lambda 中的目的。
    • @Samwise 怎么样?
    • 您的示例根本没有展示回答问题的一般简单规则:参数在运行时取值,默认参数在定义时评估。
    猜你喜欢
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 2021-02-17
    • 2016-07-03
    • 1970-01-01
    • 2011-12-20
    相关资源
    最近更新 更多