简体   繁体   English

python将lambda函数映射到列表

[英]python map a lambda function to a list

I have the impression that the following code pattern is not good 我的印象是以下代码模式不好

new_data = map(lambda x: f(x, 30), data)

because the lambda function needs to be created len(data) times, thus inefficient. 因为lambda函数需要创建len(data)次,因此效率低下。 In that case, would the following workaround help? 在这种情况下,以下解决方法是否有帮助?

g = lambda x: f(x, 30)
new_data = map(g, data)

Also, would replacing the lambda function with partial help with speed, given data is big? 另外,在给定数据很大的情况下,将替换lambda函数与速度的partial帮助?

because the lambda function needs to be created len(data) times, thus inefficient. 因为lambda函数需要创建len(数据)次,因此效率低下。

Not true, in the example the lambda definition is evaluated only once at compile time and not len(data) times - there is no need to assign it to a name for performance reasons. 事实并非如此,在示例中,lambda定义仅在编译时评估一次而不是len(data)时间 - 出于性能原因,无需将其分配给名称。 Look at Sergey's answer, he proves lambda is not expensive at all for this case. 看看谢尔盖的答案,他证明lambda在这种情况下并不昂贵。

If you do want to give it a name for the sake of clarity, you should just use a def statement instead. 如果你想为了清晰起见给它一个名字,你应该只使用def语句。 Assigning a lambda to a name is considered bad style: according to PEP-8 Programming Recommendations you should "Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier". 将lambda分配给名称被认为是错误的样式:根据PEP-8编程建议,您应该“始终使用def语句而不是将lambda表达式直接绑定到标识符的赋值语句”。 Quoting from the official style guide: 引自官方风格指南:

Yes: 是:

def f(x): return 2*x

No: 没有:

f = lambda x: 2*x:

The only difference between lambda and the one-line def is that def will give it a name (probably an extra LOAD_CONST): 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

As you can see above, both forms compile to the same bytecode. 如上所示,两种表单都编译为相同的字节码。

The lisp inspired functions map , filter and reduce always felt a bit alien in Python. lisp启发的函数mapfilterreduce在Python中总觉得有些陌生。 Since the introduction of list comprehensions (at version 2.0 IINM) they became the idiomatic way to achieve the same result. 自列表推导引入(在版本2.0 IINM)后,它们成为实现相同结果的惯用方法。 So this: 所以这:

new_data = map(lambda x: f(x, 30), data)

Is often written as: 通常写成:

new_data = [f(x, 30) for x in data]

If data is big and you are just iterating over it, generator expressions trade memory for cpu: 如果数据很大并且你只是迭代它,生成器表达式为cpu交换内存:

for value in (f(x, 30) for x in data):
    do_something_with(value)

The lispy constructs like map , filter and reduce are likely to be retired (moved to the functools module) and I recommend the use of list comprehensions and generator expressions in new code. mapfilterreduce这样的lispy结构可能会被淘汰(转移到functools模块),我建议在新代码中使用list comprehensions和generator表达式。

Last, Python is surprisingly counterintuitive regarding performance. 最后,Python在性能方面令人惊讶地违反直觉。 You should always profile in order to put your beliefs about performance in check. 您应该始终进行分析,以便对您对绩效的看法进行检查。

Bottom line: never worry about "optimizing" a damn thing until you have profiled it and know for sure it's a relevant bottleneck. 一句话:永远不要担心“优化”该死的东西,直到你对其进行分析并确定它是一个相关的瓶颈。

Lambda creates only once when map calls Lambda只在map调用时创建一次

In [20]: l = list(range(100000))

In [21]: %timeit list(map(lambda x: x * 2, l))
100 loops, best of 3: 13.8 ms per loop

In [22]: g = lambda x: x * 2

In [23]: %timeit list(map(g, l))
100 loops, best of 3: 13.8 ms per loop

As you can see, the execution time is not changed. 如您所见,执行时间不会改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM