python将lambda函数映射到列表

nos*_*nos 6 python lambda dictionary

我的印象是以下代码模式不好

new_data = map(lambda x: f(x, 30), data)
Run Code Online (Sandbox Code Playgroud)

因为lambda函数需要创建len(data)时间,因此效率低下。在这种情况下,以下解决方法会有所帮助吗?

g = lambda x: f(x, 30)
new_data = map(g, data)
Run Code Online (Sandbox Code Playgroud)

此外,如果partial数据很大,是否可以在速度帮助下替换lambda函数?

Pau*_*ine 11

因为lambda函数需要创建len(data)次,因此效率低下。

不正确,在该示例中,lambda定义在编译时只评估一次,而不是在评估时len(data)-出于性能原因,无需将其分配给名称。看一下谢尔盖(Sergey)的答案,他证明在这种情况下lambda一点也不昂贵。

如果您确实想为它起一个名字,则应该只使用def语句。将lambda分配给名称被认为是不好的样式:根据PEP-8编程建议,您应该“始终使用def语句,而不是将lambda表达式直接绑定到标识符的赋值语句”。引用官方风格指南:

是:

def f(x): return 2*x
Run Code Online (Sandbox Code Playgroud)

没有:

f = lambda x: 2*x:
Run Code Online (Sandbox Code Playgroud)

lambda和单行代码之间的唯一区别def是,def它将为其命名(可能是一个额外的LOAD_CONST):

>>> import dis

>>> def _(x):
        return f(x, 30)

>>> dis.dis(_)
  2           0 LOAD_GLOBAL              0 (f)
              2 LOAD_FAST                0 (x)
              4 LOAD_CONST               1 (30)
              6 CALL_FUNCTION            2
              8 RETURN_VALUE

>>> dis.dis(lambda x: f(x, 30))
  1           0 LOAD_GLOBAL              0 (f)
              2 LOAD_FAST                0 (x)
              4 LOAD_CONST               1 (30)
              6 CALL_FUNCTION            2
              8 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

正如您在上面看到的,两种形式都编译为相同的字节码。

lisp启发了函数mapfilter并且reduce在Python中总是感到有些陌生。自从引入列表理解(IINM 2.0版)以来,它们就成为了获得相同结果的惯用方式。所以这:

new_data = map(lambda x: f(x, 30), data)
Run Code Online (Sandbox Code Playgroud)

通常写为:

new_data = [f(x, 30) for x in data]
Run Code Online (Sandbox Code Playgroud)

如果数据很大,而您只是对其进行迭代,则生成器表达式将内存换为cpu:

for value in (f(x, 30) for x in data):
    do_something_with(value)
Run Code Online (Sandbox Code Playgroud)

mapfilter和这样的lispy构造reduce可能会被淘汰(移至functools模块中),我建议在新代码中使用列表推导和生成器表达式。

最后,Python在性能方面令人惊讶地违反直觉。您应该始终进行概要分析,以便对性能的信念进行检查。

底线:不必担心“优化”该死的事情,除非您已对其进行概要分析并确定知道这是一个相关的瓶颈。