{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 4.5 匿名函数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font color=Red>__匿名函数__</font>即是一个没有函数名字的<font color=Red>__临时使用__</font>的小函数,在Python中使用<font color=Red>__lambda__</font>表达式创建匿名函数。\n",
"lambda表达式只能包含一个表达式,不允许包含选择、循环等语法结构,其语法如下:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"lambda 参数列表 : 表达式(或条件表达式)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"相当于函数定义:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def fun(参数列表): #参数可以是一个,也可以是多个\n",
" return 表达式"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python提供了很多<font color=Red>__函数式编程__</font>的特性,如soretd(),map(),reduce(),filter()等,这些函数都支持以函数作为参数。lambda函数可以应用在函数式编程里。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"列表['58','01','9','920']元素的排序可以使用sorted()函数,sorted()语法如下:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sorted(iterable, * , key = None, reverse = False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"其中key参数可以接收函数,以函数的返回值作为排序依据。reverse = False 表示默认升序排列,可以用 reverse = True 来指定降序排列。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"lambda x: len(x)\n",
"\n",
"\n",
"ls = ['58', '01', '9', '920'] # 定义列表\n",
"print(sorted(ls)) # 对列表里的元素直接排序,即字符串的大小比较排序,默认升序\n",
"print(sorted(ls, key=int)) # 指定排序依据为int()函数,即将列表元素转换为整型后比较大小,升序排列\n",
"print(sorted(ls, key=f)) # 指定排序依据为f()函数,即列表元素的串长做排序依据,升序排列"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"上面的f()函数功能很简单,而且只是临时需要,可以使用lambda函数来代替。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ls = ['58', '01', '9', '920'] # 定义列表\n",
"print(sorted(ls, key=lambda x : len(x))) # 指定排序依据为lambda()函数,求列表元素的串长,以其做排序依据,升序排列"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font face='楷体' color='red' size=5> 练一练 </font>\n",
"\n",
"现有列表ls = [3,8,-3,-1,0,-2,-9],请(1)将列表ls中的元素按升序排序输出;(2)再按照<font color=Red>__绝对值__</font>的大小进行<font color=Red>__降序__</font>排序输出。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#提示1:reverse = True 来指定降序排列\n",
"#提示2:key = lambda x: abs(x) 来指定排序依据为列表各元素的绝对值\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 用一行代码实现判断素数的函数"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))\n",
"\n",
"print(is_prime(37)) # True"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"all函数也是 Python 内置函数,如果传入的序列中所有的布尔值都是True,all函数返回True,否则all函数返回False。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 用一条语句输出不超过100的所有素数"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(*filter(lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1))), range(2, 101)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 分两条语句"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"is_prime = lambda x: all(map(lambda f: x % f, range(2, int(x ** 0.5) + 1)))\n",
"print(*filter(is_prime, range(2, 101)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"lambda函数拥有自己的命名空间,<font color=Red>__不能访问__</font>自有参数列表之外或全局命名空间的参数。\n",
"\n",
"lambda表达式<font color=Red>__不需要return__</font>来返回值,表达式本身的计算结果就是函数的返回值。\n",
"\n",
"lambda主体是一个表达式,而不是代码块,仅能在表达式中封装有限的逻辑,<font color=Red>__不允许包含其它复杂的语句__</font>,最多只能使用类似条件表达式这样的三元运算。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font color=Red>__filter()函数__</font>用于过滤序列,过滤掉不符合条件的元素,返回符合条件的元素构成的序列。filter()接收一个函数和一个序列,将函数依次作用于每个元素,然后根据返回的布尔值决定保留还是丢弃该元素。\n",
"\n",
"filter()函数返回的是一个生成器,也是一个惰性序列,可以用 * 来<font color=Red>__解包__</font>,也可以使用list()函数将其转换为列表。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"下面的代码使用filter()和lambda(),用一行代码找出了100以内与3相关的自然数。\n",
"\n",
"所谓与3相关的数是指能被3整除或数字里包含“3”的数。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print( * filter(lambda x: x%3 == 0 or x%10 == 3 or x//10 == 3, range(101)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在Python中,可以将一些逻辑拿到函数外面,定义一个裁减过的 lambda 函数以实现目标功能。这种方式更为高效优雅,而且可以减少异常错误。\n",
"\n",
"lambda的使用可<font color=Red>__简化代码__</font>,使代码简洁清晰。不过,这种方法会在一定程度上<font color=Red>__降低代码的可读性__</font>。\n",
"\n",
"关于lambda在使用在Python社区也存在争议,Python程序员对于到底要不要使用lambda意见不一致。支持者认为使用lambda编写的代码更紧凑,更<font color=Red>__“pythonic”__</font>。反对方认为,lambda函数能够支持的功能十分有限,不支持多分支程序和异常处理程序;而且,lambda函数的功能被隐藏,对于编写代码之外的人员来说,理解lambda代码需要耗费一定的时间成本。\n",
"在实际中,是否使用lambda取决于程序员的个人喜好。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}