lambda被认为是非常Pythonic的语言,并且是Python编程中比较流行的特性之一。如此之多,以至于许多Python程序员都想尽可能地使用它们。当然,lambda有让我们的代码简洁的优势,但在项目中过度使用它们会导致滥用,从而降低我们代码的可读性和可维护性。在我们开始研究这些误用是什么之前,让我们快速回顾一下lambda。如果你很了解它们,你可以跳到下一部分。Lambda也称为lambda函数,是一种匿名函数,可以接受任意数量的参数,而只有一个表达式。它们的声明由lambda关键字表示。基本语法如下。lambdaarguments:expressionLambda最适合需要小功能且仅使用一次的情况。lambda的一个常见用途是将它们设置为内置sorted()函数中的关键参数。这是一个例子。>>>students=[('Mike','M',15),('Mary','F',14),('David','M',16)]>>>sorted(students,key=lambdax:x[2])[('Mary','F',14),('Mike','M',15),('David','M',16)]#Thestudentsresortedbyage中的许多教程它很好地解释了lambda是什么以及它可以在哪里使用,所以没有充分的理由在这里重复很多。相反,本文的目的是向您展示最常见的lambda误用,以便您在lambda用于下列情况以外的情况时可以正确使用它们。1.重新发明轮子lambda的第一个误用是忽略现有的内置函数。我们还是以sorted()函数为例。假设我们有一个字符串列表,我们想根据它们的长度对它们进行排序。当然,lambda函数lambdax:len(x)可以工作,但是直接使用内置的len()函数呢?>>>pets=['dog','turtle','bird','fish','kitty']>>>sorted(pets,key=lambdax:len(x))['dog','bird','fish','kitty','turtle']#内置len()函数>>>sorted(pets,key=len)['dog','bird','fish','kitty','turtle']这是另一个涉及使用max()函数的示例。>>>number_tuples=[(4,5,7),(3,1,2),(9,4,1)]>>>sorted(number_tuples,key=lambdax:max(x))[(3,1,2),(4,5,7),(9,4,1)]#内置的max()函数>>>sorted(number_tuples,key=max)[(3,1,2),(4,5,7),(9,4,1)]最佳实践1:在编写您自己的Lambda之前考虑内置函数。2.将其赋值给一个变量我在一些教程(包括我的一些教程)中看到过将lambda赋值给变量,但这主要是为了向初学者展示lambda本质上是函数。然而,一些初学者可能已经养成了一个好习惯,认为lambda只是一种声明短函数的便捷方式。以下代码片段向您展示了这种滥用行为。>>>divide_two_numbers=lambdax,y:x/y>>>divide_two_numbers(4,5)0.8为什么要避免这种情况?如果您还记得上面的内容,lambda应该只使用一次,因此没有理由将lambda赋值给变量。如果您确实需要使用相关功能,您应该使用def关键字声明一个常规函数,如下所示。如果您觉得使用这个简单函数的两行代码不够酷,我们可以将其重写为一行:defdivid_two_numbers_fun(x,y):returnsx/y,其工作原理相同。>>>defdivide_two_numbers_fun(x,y):...returnx/y...>>>divide_two_numbers_fun(7,8)0.875避免将lambda赋值给变量的主要原因是出于调试/维护目的,尤其是在生产/在团队合作的环境中。让我们看一个可能发生的简单例子。在真实情况下,事情会变得复杂得多。>>>divide_two_numbers(3,0)Traceback(mostrecentcallast):File"",line1,inFile"",line1,inZeroDivisionError:divisionbyzero>>>divide_two_numbers_fun(3,0)Traceback(mostrecentcalllast):File"",line1,inFile"",line1,individe_two_numbers_funZeroDivisionError:divisionbyzero正如你在上面看到的,通过一个正则函数的声明,我们确切地知道哪个函数导致错误。相反,使用lambda只告诉我们有一个lambda导致了错误。为什么不显示函数名称?这是因为lambda是匿名函数,并且它们都具有相同的名称-。你能想象如果你的同事发现了几十个错误会有多沮丧吗?好的做法#2:多次使用常规函数而不是lambda。3、高阶函数的不当使用当我们说高阶函数时,我们指的是可以通过将函数作为参数或通过返回函数来操作其他函数的函数。与当前主题相关的函数有map()、filter()和reduce(),这些函数在lambda的很多教程中都或多或少地使用过。但是,这会导致对lambda和高阶函数的某种滥用。出于演示目的,我将只在本教程中使用map()函数,但相同的原则也适用于其他高阶函数。假设我们有一个整数列表,并希望有一个包含它们的平方的列表。lambda在下面与map()函数一起使用。我们会得到一个迭代器——map()函数中的map对象,然后要将其转换为列表,我们需要在这个迭代器上调用list()函数。>>>numbers=[1,2,3,5,8]>>>squares=list(map(lambdax:x*x,numbers))>>>squares[1,4,9,25,64]实际在上面,可以通过列表推导式方便地实现相同的功能——不需要高阶函数或lambda。更简洁和可读,不是吗?当然,掌握列表理解是另一个需要另一个教程的“Pythonic特性”主题。>>>numbers=[1,2,3,5,8]>>>squares=[x*xforxinnumbers]>>>squares[1,4,9,25,64]最佳实践3:考虑使用列表推导式lambda取代了高阶函数。4.表达太笨拙,不如以前的方法普遍。但是有些程序员只是尝试通过尽可能多地使用lambda来编写尽可能多的Python代码。有时需要付出代价——可读性。假设我们有一个字符串列表,我们需要使用一个奇怪的要求对它们进行排序:单词中不同元音的数量。在sorted()函数中使用lambda,如下所示。>>>texts=['iiiiii','bag','beto','blackboard','sequoia']>>>sorted(texts,key=lambdax:len(set([lforlinlist(x)iflin['a','e','i','o','u']])))['iiiiii','bag','beto','blackboard','sequoia']它按预期工作,但绝对不是最易读的代码。下面的代码怎么样?>>>texts=['iiiiii','bag','beto','blackboard','sequoia']>>>defnumber_distinct_vowels(x):...vowels=['a','e','i','o','u']...vowels_only=[lforlinlist(x)iflinvowels]...distinct_vowels=set(all_vowels)...returnlen(distinct_vowels)...>>>sorted(texts,key=number_distinct_vowels)['iiiiii','bag','beto','blackboard','sequoia']当然,我们需要多写几行代码,但新代码不会更具可读性?最佳实践#4:如果lambda表达式太麻烦,请编写一个正则函数。总之,Lambda一直是Python初学者的难题之一,他们首先不惜一切代价避免使用它们。一段时间后,当恐惧消失后,他们开始学习lambda,并发现自己一点也不难。然后,他们开始使用lambda,但不幸的是有些人可能会过度使用lambda,从而导致如上所述的各种滥用。我希望这篇文章可以帮助解决其中的一些问题。通过避免这些误用并遵循良好的实践技巧,我敢打赌,正确使用lambda的Python代码将更具可读性和可维护性。