系列文章目录
第一章 初识python
第二章 变量
第三章 基础语句
第四章 字符串str
第五章 列表list []
第六章 元组tuple ( )
第七章 字典dict {}
第八章 集合set {}
第九章 常用操作
文章目录
- 系列文章目录
- 10.1函数的作用
- 10.2函数的使用步骤
- 定义函数
- 调用函数
- 函数的注意事项
- 10.3函数的参数作用
- 10.4函数的返回值作用
- return的特点
- 10.5函数的说明文档
- 10.6函数嵌套
- 10.7变量作用域
- 修改全局变量global
- 10.8多函数程序执行流程
- 10.9函数的返回值作为参数传递
- 10.10函数返回多个返回值
- 10.11函数的参数
- 位置参数
- 关键字参数
- 缺省参数
- 不定长参数
- 10.12拆包和交换两个变量的值
- 拆包
- 交换变量值
- 10.13 引用
- id() 返回变量的十进制地址
- 引用当做实参去传递
- 10.14可变和不可变类型
- 10.15递归
- 10.16 lambda表达式(匿名函数)
- lambda的参数形式
- 无参数
- 一个参数
- 默认参数
- 可变参数 *args
- 可变参数 **kwargs
- lambda的应用
- 带判断的lambda
- 列表数据按字典key的值排序
- 10.17 高阶函数
- 10.17.1 体验高阶函数
- abs绝对值
- round四舍五入
- 10.17.2 内置高阶函数
- map()
- reduce()累积
- filter()过滤
10.1函数的作用
函数就是将一段具有独立功能的代码块
整合到一个整体并命名,在需要的位置调用这个名称
即可完成对应的需求。
函数在开发过程中,可以更高效的实现代码重用
。
10.2函数的使用步骤
定义函数
def 函数名(参数):
代码1
代码2
…
调用函数
函数名(参数)
注意:
1.不同的需求,参数可有可无。
2.在Python中,函数必须先定义后使用
。
# 因为函数要先定义再调用,所以步骤2和3要在步骤1的上面书写
# 2.确定选择功能界面: 显示余额 存款 取款; # 3.封装函数
def sel_func():
print('显示余额')
print('存款')
print('取款')
# 1.搭建整体框架
# 输入密码登录后显示功能; 查询余额后显示功能; 取完钱后显示功能;
print('恭喜您登录成功')
# 显示功能界面 # 4.在需要的位置调用函数
sel_func()
print("您的余额是10000000")
# 显示功能界面 # 4.在需要的位置调用函数
sel_func()
print('取了100元钱')
# 显示功能界面 # 4.在需要的位置调用函数
sel_func()
函数的注意事项
函数是先定义后调用,如果先调用会报错。
如果没有调用函数,函数里面的代码不会执行。
函数执行流程:
当调用函数的时候,解释器回到定义函数的地方去执行下方缩进的代码,当这些代码执行完,回到调用函数的地方继续向下执行。
定义函数的时候,函数体内部下方缩进的代码并没有执行。
10.3函数的参数作用
函数的参数:函数调用的时候可以传入真实数据,增大函数的使用的灵活性
- 形参:函数定义时书写的参数(非真实数据)
- 实参:函数调用时书写的参数(真实数据)
# 定义函数时同时定义了接收用户数据的参数a和b,a和b是形参
def add_num2(a, b):
result = a + b
print(result)
# 调用函数时传入了真实的数据19 和 20,真实数据为实参
add_num2(10, 20)
10.4函数的返回值作用
在函数中,如果需要返回结果给用户需要使用函数返回值。
写法:return 表达式
return返回结果给函数调用的地方
return的特点
return 作用:
1.负责函数返回值
2.退出当前函数:导致return下方的所有代码(函数体内部)不执行
10.5函数的说明文档
思考: 定义一个函数后,程序员如何书写程序能够快速提示这个函数的作用?
答: 注释
思考:如果代码多,我们是不是需要在很多代码中找到这个函数定义的位置才能看到注释?如果想更方便的查看函数的作用怎么办?
答: 函数的说明文档
函数的说明文档也叫函数的文档说明。
语法: help(任意函数名)
help函数作用:查看函数的说明文档(函数的解释说明的信息)
定义函数的同时定义一个说明文档
定义函数的说明文档
语法:
def 函数名(参数):
""" 说明文档的位置 """
代码
......
第一行这个位置打多行注释的形式写提示文字,这就是说明文档,并且只有在函数内部缩进的第一行的位置书写的多行注释才是说明文档。
查看函数的说明文档
help(函数名)
函数的说明文档的高级使用
"""敲回车"""
10.6函数嵌套
所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。
10.7变量作用域
变量作用域指的是变量生效的范围,主要分为两类:局部变量和全局变量。
- 局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
局部变量的作用: 在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。 - 全局变量
所谓全局变量,指的是在函数体内、外都能生效的变量。
思考: 如果有一个数据,在函数A和函数B中都要使用,该怎么办?
答: 将这个数据存储在一个全局变量里面
修改全局变量global
想要修改全局变量x是999
global x # 声明x为全局变量
x= 999
总结:
1.如果在函数里面直接把变量x=999赋值,此时的x不是全局变量的修改,而是相当于在函数内部声明了一个新的局部变量
2.函数体内部修改全局变量:先global声明x为全局变量,然后再变量重新赋值
10.8多函数程序执行流程
- 共用全局变量
10.9函数的返回值作为参数传递
10.10函数返回多个返回值
def test1():
# return 1, 2 # 默认返回的是元组(1, 2)
# return (10,20) # (10, 20)
# return [10,20] # [10, 20]
return {'name': "python", 'age': 22} # {'name': 'python', 'age': 22}
x = test1()
print(x)
注意:
1.return 表达式1,表达式2…写法,返回多个数据的时候,默认是元组
类型。
2.return后面可以连接列表、元组或字典,以返回多个值。
10.11函数的参数
位置参数
位置参数: 调用函数时根据函数定义的参数位置来传递参数。
def user_info(name, age, gender):
print(f'您的名字是{name},年龄{age},性别是{gender}')
user_info("意境", 18, '男')
注意: 传递和定义参数的顺序及个数必须一致
,不一致会报错。顺序与定义不一致会导致数据无意义。
关键字参数
函数调用,通过“键=值"
形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
def user_info(name, age, gender):
print(f'您的名字是{name},年龄{age},性别是{gender}')
user_info("意境", age=18, gender='男')
user_info("张三", gender='女', age=22)
注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面
不然会报错,但关键字参数之间不存在先后顺序。
缺省参数
缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值 (注意:所有位置参数必须出现在默认参数前,包括函数定义和调用) 。
def user_info(name, age, gender='男'):
print(f'您的名字是{name},年龄{age},性别是{gender}')
user_info("意境", 18) # 没有为缺省参数传值,表示使用默认值
user_info("张三", age=22, gender='女') # 为缺省参数传值,使用这个值,即修改了默认值
注意: 函数调用时,如果为缺省参数传值则修改默认参数值,否则使用这个默认值。
不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
- 包裹位置传递(不定长位置参数)
*args就是一个形参,这个形参接收所有不定长位置参数用的,必须要写的,但是args可以替换成任意的其他的单词,一般用args。python解释器底层的代码对于接收不定长位置参数变量名(形参名)用的都是args。返回一个元组
def user_info(*args):
print(args)
user_info("意境") # ('意境',)
user_info("张三", 22) # ('张三', 22)
注意: 传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组
类型,不管将来传不传数据都是元组,这就是包裹位置传递。
- 包裹关键字传递(不定长关键字参数)
**
必须要写的,但是kwargs可以替换成任意的其他的单词,python解释器底层的代码对于接收不定长关键字参数变量名(形参名)用的都是kwargs。返回一个字典
def user_info(**kwargs):
print(kwargs)
# {'name': '意境', 'age': 18, 'id': 52}
user_info(name="意境", age=18, id=52)
综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。返回的是一个字典。
10.12拆包和交换两个变量的值
组包:把零散的数据组合到一个整体的过程。
拆包
拆包:把一个整体数据再把它单独拆开。
- 拆包:元组
def test():
return 5, 2
x, y = test()
print(x) # 5
print(y) # 2
- 拆包:字典
dict1 = {'name': "清风", "age": 23}
a, b = dict1
# 对字典进行拆包,取出来的是字典的key
print(a) # name
print(b) # age
print(dict1[a]) # 清风
print(dict1[b]) # 23
交换变量值
需求: 有变量 a = 10 和b = 20,交换两个变量的值
- 方法一
借助第三变量存储数据
a = 10
b = 20
# 1,定义中间变量
c = 0
# 2.将a的数据存储到c
c = a
# 3.将b的数据20赋值到a,此时a = 20
a = b
# 4.将之前c的数据10赋值到b,此时b = 10
b = c
print(a) # 20
print(b) # 10
- 方法二
a, b = 10, 20
a, b = b, a
print(a) # 20
print(b) # 10
10.13 引用
在python中,值是靠引用
来传递来的。
id() 返回变量的十进制地址
我们可以用 id() 来判断两个变量是否为同一个值的引用。我们可以将id值理解为那块内存的地址标识,返回变量在内存当中的十进制地址。
# 不可变类型 int类型
a = 10
b = a
print(b) # 10
print(id(a)) # 140710441051208
print(id(b)) # 140710441051208
a = 2
print(b) # 10,说明int类型为不可变类型
#因为修改了a的数据,内存要开辟另外一份内存取存储2,所以id检测到两个变量不同了
print(id(a)) # 140710441050952,此时得到的是数据2的内存地址
print(id(b)) # 140710441051208
# 可变类型:列表
l1 = [10, 20]
l2 = l1
print(l2) # [10, 20]
print(id(l1)) # 3036634911808
print(id(l2)) # 3036634911808
l1.append(66)
print(l1) # [10, 20, 66]
print(l2) # [10, 20, 66]
print(id(l1)) # 3036634911808
print(id(l2)) # 3036634911808
引用当做实参去传递
10.14可变和不可变类型
所谓可变类型与不可变类型是指: 数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变。
- 可变类型
列表
字典
集合 - 不可变类型
整型
浮点型
字符串
元组
10.15递归
递归的应用场景
递归是一种编程思想,应用场景:
1.在我们日常开发中,如果要遍历一个文件夹下面所有的文件,通常会使用递归来实现;
2.在后续的算法学习中,很多算法都离不开递归,例如: 快速排序。
递归的特点
- 函数内部自己调用自己
- 必须有出口
举个例子
6以内数字累加和
代码:
def sum_numbers(num):
# 1.如果是1,直接返回1 -- 出口
if num == 1:
return 1
# 2.如果不是1,重复执行累加并返回结果
return num + sum_numbers(num - 1)
sum_result = sum_numbers(6)
# 输出结果为 21
print(sum_result)
10.16 lambda表达式(匿名函数)
lambda的应用场景
如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda简化。
lambda语法
lambda [参数列表] : 表达式
注意:
- lambda表达式的参数可有可无,函数的参数在lambda表达式中完全适用。
- lambda表达式能接收任何数量的参数但只能返回一个表达式的值。
# 函数
def func1():
return 666
print(func1)
print(func1())
# lambda表达式
func2 = lambda: 111
print(func2)
print(func2())
注意:直接打印lambda表达式,输出的是此lambda的内存地址。
示例:计算两个数的和
# 函数实现
def add1(x, y):
return x + y
print(add1(1, 2)) # 3
# lambda实现
print( (lambda z, w: z + w)(1, 2) ) # 3
lambda的参数形式
无参数
func1 = lambda: 999
print(func1())# 999
一个参数
func1 = lambda a: a
print(func1(999)) # 999
默认参数
lambda key=value : 表达式
func1 = lambda x, y, z=100: x + y + z
print(func1(11, 55)) # 166
可变参数 *args
func1 = lambda *args: args
print(func1(10, 13, 15)) # (10, 13, 15)
注意:这里的可变参数传入到lambda之后,返回值为元组。
可变参数 **kwargs
func1 = lambda **kwargs: kwargs
print(func1(name="大美女", age=20)) # {'name': '大美女', 'age': 20}
lambda的应用
带判断的lambda
func1 = lambda x, y: x if x > y else y
print(func1(100, 222)) # 222
列表数据按字典key的值排序
students = [
{'name': 'TOM', 'age': 20},
{'name': 'ROSE', 'age': 19},
{'name': 'Jack', 'age': 22}
]
# 按age值升序排列
students.sort(key=lambda x: x['age'])
print(students)
# 按age值降序排列
students.sort(key=lambda x: x['age'], reverse=True)
print(students)
10.17 高阶函数
把函数作为参数传入
,即一个函数作为另外一个函数参数传入,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式。
10.17.1 体验高阶函数
abs绝对值
在Python中,abs()
函数可以完成对数字求绝对值计算。
print(abs(-10)) # 10
round四舍五入
round()
函数可以完成对数字的四舍五入计算。
print(round(1.2)) # 1
print(round(1.5)) # 2
示例:任意两个数字,按照指定要求整理数字后再进行求和计算。
- 方法1
def add_number(x, y):
return abs(x) + abs(y)
result = add_number(-5, 2)
print(result) # 7
- 方法2 高阶函数
def add_number(x, y, f):
return f(x) + f(y)
result = add_number(-5, 2, abs)
print(result) # 7
result = add_number(1.1, 1.6, round)
print(result) # 3
注意:
两种方法对比之后,发现,方法2的代码会更加简洁,函数灵活性更高。
函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快。
10.17.2 内置高阶函数
map()
map(func, lst)
,参数1是一个函数名,参数2是一个列表序列,将传入的函数变量func作用到Ist变量的每个元素中,并将结果组成新的列表(Python2解释器环境下)
/ 迭代器(Python3)
返回。
需求: 计算 list1 序列中各个数字的2次方。
list1 = [1, 2, 3, 4, 5]
def func(x):
return x ** 2
result = map(func, list1)
print(result) # <map object at 0x000002174A2C9480>
print(list(result)) # [1, 4, 9, 16, 25]
reduce()累积
reduce(func,lst)
,其中func必须有两个参数。每次func计算的结果继续和序列的下一个元素做累积计算。
注意: reduce()传入的参数func必须接收2个参数。
需求: 计算 list1 序列中各个数字的累加和。
import functools
list1 = [1, 2, 3, 4, 5]
def func(x,y):
return x+y
result = functools.reduce(func, list1)
print(result) # 15
filter()过滤
filter(func,lst)
函数用于过滤序列,过滤掉不符合条件的元素,返回一个 filter 对象。如果要转换为列表,可以使用 list() 来转换。
list1 = [1, 2, 3, 4, 5]
def func(x):
return x % 2 == 0
result = filter(func, list1)
print(result) # <filter object at 0x000002511B4B9480>
print(list(result)) # [2, 4]