lambda被以为是十分Python的言语,是Python编程中比较受欢迎的功用之一。 如此之多,以致于许多Python顺序员都想尽能够地运用它们。
当然,lambda具有使我们的代码繁复的优势,但是在项目中过度运用它们会招致滥用,从而降低我们代码的可读性和可维护性。
在末尾研讨这些误用是什么之前,让我们先快速回忆一下lambda。 假设您对它们十分了解,则可以跳到下一部分。
Lambda,也称为lambda函数,是匿名函数,可以接受恣意数量的参数,而只要一个表达式。 它们的声明由lambda关键字表示。 基本语法如下。
lambda arguments: expression
Lambda最适宜需求小的功用且仅运用一次的中央。 lambda的一种常见用法是将其设置为内置sorted()函数中的关键参数。 这是一个例子。
>>> students = [('Mike', 'M', 15), ('Mary', 'F', 14), ('David', 'M', 16)]
>>> sorted(students, key=lambda x: x[2])
[('Mary', 'F', 14), ('Mike', 'M', 15), ('David', 'M', 16)]
# The students are sorted by age
许多教程在解释lambda是什么以及可以在哪里运用lambda方面做得很好,因此,没有充沛的理由在这里重复少量的解说。
相反,本文的目的是向您展现最常见的lambda误用,以便在以下所列状况以外的其他状况下运用lambda时,您能够会正确运用它们。
1.重新发明轮子
lambdas的第一个误用是疏忽了现有的内置函数。
让我们依然以sorted()函数为例。 假定我们有一个字符串列表,我们想运用它们的长度对它们停止排序。
当然,lambda函数lambda x:len(x)可以任务,但是直接运用内置的len()函数怎样样?
>>> pets = ['dog', 'turtle', 'bird', 'fish', 'kitty']
>>> sorted(pets, key=lambda x: len(x))
['dog', 'bird', 'fish', 'kitty', 'turtle']
# The built-in len() function
>>> 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=lambda x: max(x))
[(3, 1, 2), (4, 5, 7), (9, 4, 1)]
# The built-in max() function
>>> sorted(number_tuples, key=max)
[(3, 1, 2), (4, 5, 7), (9, 4, 1)]
优秀实际1:在编写本人的Lambda之前先思索一下内置函数。
2.将其分配给变量
在一些教程(包括我的一些教程)中,我曾经看到了将lambdas分配给变量的办法,但是它主要是向初学者展现lambdas本质上是函数。
但是,某些初学者能够已将其作为一种好习气,并以为lambda只是声明短函数的便捷方式。 以下代码片段向您展现了这种滥用。
>>> divide_two_numbers = lambda x, y: x / y
>>> divide_two_numbers(4, 5)
0.8
为什么要避免这种状况? 假设您还记得下面提到的内容,那么lambda应该只运用一次,因此没有理由将lambda分配给变量。
假设确实需求运用相关功用,则应运用def关键字来声明一个常规函数,如下所示。
假设您以为运用此复杂功用的两行代码并不酷,我们可以将其重写为一行:defdivid_two_numbers_fun(x,y):前往x / y,其任务方式相反。
>>> def divide_two_numbers_fun(x,y):
... return x / y
...
>>> divide_two_numbers_fun(7, 8)
0.875
避免为变量分配lambda的主要缘由是出于调试/维护的目的,尤其是在消费/团队协作环境中。
让我们看一个复杂的例子,能够发作的事情。 在实践状况下,事情能够会变得复杂得多。
>>> divide_two_numbers(3, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
ZeroDivisionError: division by zero
>>> divide_two_numbers_fun(3, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in divide_two_numbers_fun
ZeroDivisionError: division by zero
如您在下面看到的,经过常规函数的声明,我们确切地知道哪个函数招致了错误。 相比之下,运用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(lambda x: x * x, numbers))
>>> squares
[1, 4, 9, 25, 64]
实践上,可以经过列表了解方便地完成相反的功用-不需求高阶函数或lambda。 愈加繁复易读,不是吗?
当然,掌握列表了解才能是另一个" Pythonic功用"主题,需求另一个教程。
>>> numbers = [1, 2, 3, 5, 8]
>>> squares = [x * x for x in numbers]
>>> squares
[1, 4, 9, 25, 64]
优秀实际3:思索运用带列表推导的lambda交流高阶函数。
4.表达式太笨拙
这比以前的办法少见。 但是一些顺序员只是尽能够地运用lambda来努力编写最多的Python代码。 有时需求付出一定的代价-可读性。
假定我们有一个字符串列表,我们需求运用一个奇异的要求对它们停止排序:单词中不同元音的数量。 在sorted()函数中运用lambda如下所示。
(责任编辑:admin)