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启发了函数map
,filter
并且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)
像map
,filter
和这样的lispy构造reduce
可能会被淘汰(移至functools
模块中),我建议在新代码中使用列表推导和生成器表达式。
最后,Python在性能方面令人惊讶地违反直觉。您应该始终进行概要分析,以便对性能的信念进行检查。
底线:不必担心“优化”该死的事情,除非您已对其进行概要分析并确定知道这是一个相关的瓶颈。
归档时间: |
|
查看次数: |
11707 次 |
最近记录: |