master
/ 4.4 匿名函数.ipynb

4.4 匿名函数.ipynb @masterview markup · raw · history · blame

Notebook

4.5 匿名函数

__匿名函数__即是一个没有函数名字的__临时使用__的小函数,在Python中使用__lambda__表达式创建匿名函数。 lambda表达式只能包含一个表达式,不允许包含选择、循环等语法结构,其语法如下:

In [ ]:
lambda 参数列表 : 表达式或条件表达式

相当于函数定义:

In [ ]:
def fun(参数列表)    #参数可以是一个,也可以是多个
    return 表达式

Python提供了很多__函数式编程__的特性,如soretd(),map(),reduce(),filter()等,这些函数都支持以函数作为参数。lambda函数可以应用在函数式编程里。

列表['58','01','9','920']元素的排序可以使用sorted()函数,sorted()语法如下:

In [ ]:
sorted(iterable, * , key = None, reverse = False)

其中key参数可以接收函数,以函数的返回值作为排序依据。reverse = False 表示默认升序排列,可以用 reverse = True 来指定降序排列。

In [ ]:
lambda x: len(x)


ls = ['58', '01', '9', '920']            # 定义列表
print(sorted(ls))                        # 对列表里的元素直接排序,即字符串的大小比较排序,默认升序
print(sorted(ls, key=int))               # 指定排序依据为int()函数,即将列表元素转换为整型后比较大小,升序排列
print(sorted(ls, key=f))                 # 指定排序依据为f()函数,即列表元素的串长做排序依据,升序排列

上面的f()函数功能很简单,而且只是临时需要,可以使用lambda函数来代替。

In [ ]:
ls = ['58', '01', '9', '920']            # 定义列表
print(sorted(ls, key=lambda x : len(x))) # 指定排序依据为lambda()函数,求列表元素的串长,以其做排序依据,升序排列

练一练

现有列表ls = [3,8,-3,-1,0,-2,-9],请(1)将列表ls中的元素按升序排序输出;(2)再按照__绝对值__的大小进行__降序__排序输出。

In [ ]:
#提示1:reverse = True 来指定降序排列
#提示2:key = lambda x: abs(x)  来指定排序依据为列表各元素的绝对值

用一行代码实现判断素数的函数

In [ ]:
is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))

print(is_prime(37))  # True

all函数也是 Python 内置函数,如果传入的序列中所有的布尔值都是True,all函数返回True,否则all函数返回False。

用一条语句输出不超过100的所有素数

In [ ]:
print(*filter(lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1))), range(2, 101)))

分两条语句

In [ ]:
is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))
print(*filter(is_prime, range(2, 101)))

lambda函数拥有自己的命名空间,__不能访问__自有参数列表之外或全局命名空间的参数。

lambda表达式__不需要return__来返回值,表达式本身的计算结果就是函数的返回值。

lambda主体是一个表达式,而不是代码块,仅能在表达式中封装有限的逻辑,__不允许包含其它复杂的语句__,最多只能使用类似条件表达式这样的三元运算。

__filter()函数__用于过滤序列,过滤掉不符合条件的元素,返回符合条件的元素构成的序列。filter()接收一个函数和一个序列,将函数依次作用于每个元素,然后根据返回的布尔值决定保留还是丢弃该元素。

filter()函数返回的是一个生成器,也是一个惰性序列,可以用 * 来__解包__,也可以使用list()函数将其转换为列表。

下面的代码使用filter()和lambda(),用一行代码找出了100以内与3相关的自然数。

所谓与3相关的数是指能被3整除或数字里包含“3”的数。

In [ ]:
print( * filter(lambda x: x%3 == 0 or x%10 == 3 or x//10 == 3, range(101)))

在Python中,可以将一些逻辑拿到函数外面,定义一个裁减过的 lambda 函数以实现目标功能。这种方式更为高效优雅,而且可以减少异常错误。

lambda的使用可__简化代码__,使代码简洁清晰。不过,这种方法会在一定程度上__降低代码的可读性__

关于lambda在使用在Python社区也存在争议,Python程序员对于到底要不要使用lambda意见不一致。支持者认为使用lambda编写的代码更紧凑,更__“pythonic”__。反对方认为,lambda函数能够支持的功能十分有限,不支持多分支程序和异常处理程序;而且,lambda函数的功能被隐藏,对于编写代码之外的人员来说,理解lambda代码需要耗费一定的时间成本。 在实际中,是否使用lambda取决于程序员的个人喜好。

In [ ]: