我的施工之路
目前已完成,以下五期Python专题总结:
1我的施工计划
2数字专题
3字符串专题
4列表专题
5流程控制专题
6编程风格专题
今天是Python函数专题,目录结构:
- Python 函数专题
- 基础部分
- 1 函数组成
- 2 引用传参
- 3 默认参数与关键字参数
- 4 可变参数
- 5 内置函数
- 进阶部分
- 6 偏函数
- 7 递归函数
- 8 匿名函数
- 9 高阶函数
- 10 嵌套函数
- 总结
Python 函数专题
函数是一个接受输入、进行特定计算并产生输出的语句集。
我们把一些经常或反复被使用的任务放在一起,创建一个函数,而不是为不同的输入反复编写相同的代码。
Python提供了print
、sorted
、max
、map
等内置函数,但我们也可以创建自己的函数,称为用户定义函数。
基础部分
1 函数组成
如下自定义函数:
可以看到函数主要组成部分:
- 函数名:
foo
- 函数形参:
nums
-
:
: 函数体的控制字符,作用类似Java
或C++
的一对{}
- 缩进:一般为4个字符
-
"""
:为函数添加注释 -
return
: 函数返回值
以上函数求出列表nums
中的所有偶数并返回,通过它了解Python函数的主要组成部分。
2 引用传参
定义好一个函数后,使用:函数名+()+实参,调用函数,如下方法:
其中[10,2,5,4]
为实参,它通过by reference
方式传给形参nums
,即nums
指向列表头,而不是重新复制一个列表给nums
.
再看一个引用的例子:
如下调用:
实参lst
和形参x
都指向同一个列表:
因此,对x[0]
修改实际就是对实参lst
的修改,结果如下:
但是,有时在函数内部形参指向改变,因此实参与形参的指向分离,如下例子:
调用:
x
被传参后初始指向lst
,如下所示:
但是,执行x = [20, 30, 40]
后,对象x
重新指向一个新的列表对象[20,30,40]
:
因此,对于x
内元素的任何修改,都不会同时影响到lst
,因为指向已经分离。
3 默认参数与关键字参数
Python函数的参数,可以有初始默认值,在调用时如果不赋值,则取值为默认值,如下例子:
调用foo
函数,没有为height
传参,所以取为默认值1.0
:
使用默认值有一点需要区分,有的朋友会与关键字参数混淆,因为它们都是para=value
的结构,但是有一个很明显的不同:默认值是声明在函数定义时,关键字参数是在函数调用时使用的此结构。如下例子:
确定以上调用后,才确定width
和length
是关键字参数,并且关键字参数不必按照形参表的顺序调用。
4 可变参数
Java
和C++
在解决同一个函数但参数个数不同时,会使用函数重载的方法。Python使用可变参数的方法,非常灵活。
可变参数是指形参前带有*
的变量,如下所示:
我们可以像下面这样方便的调用:
如上,带一个星号的参数被传参后,实际被解释为元组对象
。我们还可以这样调用:
5 内置函数
总结完函数的参数后,再举几个Python内置的常用函数。
pow
大部分朋友应该知道pow
是个幂次函数,比如求
:
除此以外,pow
还有第三个参数,使用更高效的算法实现求幂后再求余数:
max,min
max,min用来求解最大最小值,实现relu
函数:
sorted
sorted函数完成对象排序,它能接收一个指定排序规则的函数,完成定制排序。如下,根据字典值绝对值从小到大排序:
进阶部分
Python有一个专门操作函数的模块:functools
,能实现一些关于函数的特殊操作。
6 偏函数
偏函数固定函数的某些参数后,重新生成一个新的函数。
通常用法,当函数的参数个数太多,需要简化时,使用partial
创建一个新的函数。
假设我们要经常调用int
函数转换二进制字符,设置参数base
为2:
为了避免每次都写一个参数base,我们重新定义一个函数:
以后每次转化字符串时,只需int2('1010
)即可,更加简便。
偏函数也能实现上述功能:
那么有的朋友会问,偏函数就是个鸡肋,重新定义的int2
更加直观容易理解,这个角度讲确实是这样。但是int2
不能再接收base
参数,但是intp
函数还是能接收base
参数,依然保留了原来的参数:
可能看到这里的读者还是有些迷糊,不太确定怎么使用偏函数。可以先记住:修改内置函数的默认参数,就像内置函数int
默认参数base等于10,使用偏函数调整默认base值为2.
7 递归函数
递归函数是指调用自身的函数。如下使用递归反转字符串:
reverseStr
函数里面又调用了函数reverseStr
,所以它是递归函数。
使用递归函数需要注意找到正确的递归基,防止陷入无限递归。
更多使用递归的例子大家可参考此公众号之前推送。
8 匿名函数
匿名函数是指使用lambda
关键字创建的函数。它的标准结构如下:
表达式的计算值即为lambda
函数的返回值。
如下lambda
函数:
它等价于下面的f
函数:
lambda函数常做为max
,sorted
,map
,filter
等函数的key参数。
9 高阶函数
可以用来接收另一个函数作为参数的函数叫做高阶函数。
如下f
有一个参数g
,而g
又是函数,所以f
是高阶函数:
Python 中经常会遇到高阶函数,今天介绍几个内置的常用的高阶函数。
map
map 函数第一个参数为函数,它作用于列表中每个的元素。
如下,列表中的单词未按照首字母大写其他字符小写的规则,使用map
一一capitalize
每个元素:
结果:
reduce
reduce 高阶函数实现化简列表,它实现的效果如下:
如下例子,函数f
等于x+y
,求得两数之和,然后再与第三个数相加,依次下去,直到列表尾部,进而得到整个列表的和:
以上reduce
求解过程等于:
需要注意:reduce
函数要求f
必须带2个参数,只有这样才能完成归约化简。
10 嵌套函数
嵌套函数是指里面再嵌套函数的函数。
如下例子,将列表转化为二叉树。已知列表nums
,
nums = [3,9,20,None,None,15,7],转化为下面二叉树:
二叉树定义:
构建满足以上结构的二叉树,可以观察到:树的父节点和左右子节点的关系:
基于以上公式,再使用递归构建二叉树。
递归基情况:
递归方程:
根据以上分析,得到如下代码,list_to_binarytree
函数是嵌套函数,它里面还有一个level
子函数:
通常使用嵌套函数的场景:实现一个功能只需要编写2个函数,写成一个class
好像显得有些不必要,写成嵌套后更简洁,并且某些参数能共享,亲和性会更好。不妨体会上面的nums
参数。
总结
函数专题主要总结了以下:
- Python 函数专题
- 基础部分
- 1 函数组成
- 2 引用传参
- 3 默认参数与关键字参数
- 4 可变参数
- 5 内置函数
- 进阶部分
- 6 偏函数
- 7 递归函数
- 8 匿名函数
- 9 高阶函数
- 10 嵌套函数
- 总结
《end》