E731不分配lambdaexpression式,使用def

每当我使用lambdaexpression式时,我都会得到这个pep8警告。 lambdaexpression式不推荐? 如果不是为什么?

您遇到的PEP-8中的build议是:

总是使用def语句而不是将lambdaexpression式直接绑定到名称的赋值语句。

是:

def f(x): return 2*x 

没有:

 f = lambda x: 2*x 

第一种forms意味着结果函数对象的名称是特定的'f'而不是通用的''。 一般而言,这对回溯和string表示更有用。 赋值语句的使用消除了lambdaexpression式可以提供的明确的def语句的唯一好处(也就是说它可以embedded到更大的expression式中)

将lambdas分配给名称基本上只是复制了def的function – 一般来说,最好是采取一种单一的方式来避免混淆,提高清晰度。

lambda的合法用例是你想使用一个函数而不分配它的地方,例如:

 sorted(players, key=lambda player: player.rank) 

这是故事,我有一个简单的lambda函数,我使用了两次。

 a = map(lambda x : x + offset, simple_list) b = map(lambda x : x + offset, another_simple_list) 

这只是为了表示,我已经遇到了几个不同的版本。

现在,为了保持干爽,我开始重用这个常见的lambda。

 f = lambda x : x + offset a = map(f, simple_list) b = map(f, another_simple_list) 

在这一点上,我的代码质量检查器抱怨lambda是一个命名函数,所以我把它转换成一个函数。

 def f(x): return x + offset a = map(f, simple_list) b = map(f, another_simple_list) 

现在检查器抱怨一个函数必须由一个空白行前后界定。

 def f(x): return x + offset a = map(f, simple_list) b = map(f, another_simple_list) 

在这里,我们现在有6行代码,而不是原来的2行,没有增加可读性,没有增加pythonic。 在这一点上,代码检查器抱怨没有文档的function。

在我看来,这个规则最好在有意义时避免和破坏,使用你的判断。

Lattyware是绝对正确的:基本上PEP-8希望你避免像

 f = lambda x: 2 * x 

而是使用

 def f(x): return 2 * x 

但是,正如最近的一个bug报告 (2014年8月)中所述,现在符合以下声明:

 af = lambda x: 2 * x a["f"] = lambda x: 2 * x 

由于我的PEP-8检查器还没有正确实现,所以我暂时closures了E731。

我也遇到了一个甚至不可能使用def(ined)函数的情况。

 class SomeClass(object): # pep-8 does not allow this f = lambda x: x + 1 # NOQA def not_reachable(self, x): return x + 1 @staticmethod def also_not_reachable(x): return x + 1 @classmethod def also_not_reachable(cls, x): return x + 1 some_mapping = { 'object1': {'name': "Object 1", 'func': f}, 'object2': {'name': "Object 2", 'func': some_other_func}, } 

在这种情况下,我真想做一个属于这个class级的地图。 映射中的一些对象需要相同的function。 把一个命名函数放在类之外是不合逻辑的。 我还没有find从类内部引用方法(staticmethod,classmethod或normal)的方法。 代码运行时SomeClass尚不存在。 所以从课上提到它也是不可能的。

Lambdas可以用于懒惰的评估,因此推迟某些昂贵的操作,直到实际需要结果为止。

我刚刚遇到了一个案例(在代码竞争/实践问题),我计算了相对昂贵的pow()函数(相对昂贵,因为input包含50万个testing用例),对于3种不同的情况和3个特定的组合案例。 为了清楚代码,我将计算所有3个案例,然后返回当前请求实际需要的3个组合。

不幸的是,这对某些input产生了TLE(“超出时间限制”)。

通过使用lambda来推迟昂贵的pow()操作,我能够解决TLE问题,因为只有与当前请求相关的计算才被实际调用。

所以我认为这是一个E731警告不是真的适用,应该被禁用的情况。