一、复习
1.函数的声明
def 函数名(参数列表):
函数体
lambda 参数列表: 返回值
(重点)函数声明的时候函数体不会执行!
2.函数调用
函数名() <---> 变量() - 要求变量中存储的地址对应的值是function
调用过程:
回到函数声明的位置
传参 - 保证每个参数都有值
执行函数体
确定返回值
回到函数调用的位置
3.函数的参数
位置参数和关键参数
参数默认值
参数类型说明
不定长参数
4.返回值
怎么确定函数的返回值
怎么获取函数的返回值 - 函数调用表达式
5.全局变量和局部变量
6.函数作为量: 声明函数就是声明一个类型是function的变量,函数名就是变量名
例如:
def func1():
return 10
a = 10
# func1和a是一样的,都是变量
print(a - 1)
print(func1())
a = [1, 2]
print(a[0])
func1 = 'abc'
print(func1[0])
# lambda x: x 和 10是一样的,都是值
num = 10
list1 = [10]
func2 = lambda x: x
list2 = [lambda x: x]
func2(10)
list2[0]('abc')
def yt_sums(*num):
"""求多个数的和"""
# num = (1, 2, 3, 4)
sum1 = 0
for x in num:
sum1 += x
return sum1
def yt_product(*num):
sum1 = 1
for x in num:
sum1 *= x
return sum1
# print(yt_sums(1, 2, 3))
# print(yt_product(2, 4, 6))
def opration(char: str, *nums):
# char = '+', nums = (1, 2, 3, 4) *nums 相当于 1, 2, 3, 4
if char == '+':
return yt_sums(*nums) # yt_sums(1,2,3,4)
else:
return yt_product(*nums)
print(opration('+', 1, 2, 3, 4))
print(opration('*', 1, 2, 3, 4))
运行结果:
9
10
1
a
10
24
二、递归函数
实际开发的时候,能不用递归就不用
1.什么是递归函数
函数中调用函数本身的函数就是递归函数
2.递归的作用:循环能做的事情递归函数都能做
例如:
def func1():
print('====')
func1()
a = 0
def func2():
global a
if a < 5:
print('~~~~~')
a += 1
func2()
func2()
运行结果:
~~~~~
~~~~~
~~~~~
~~~~~
~~~~~
3.怎么写递归函数:f(n)
第一步:确定临界值 - 循环结束的条件,在临界值的地方要让函数结束!
第二步:找关系 - 找当次循环和上次循环的关系;
找f(n)和f(n-1)的关系
第三步: 假设函数f的功能已经实现,通过f(n-1)来实现f(n)的功能
例如:
# 实现:1+2+3+...+n
# a.for循环
# n = 20
# # sum1 = 0
# # for x in range(n+1):
# # sum1 += x
# # print(sum1)
# b.递归
def yt_sum(n):
# 1.找临界值
if n == 1:
return 1
# 2. 找关系
"""
找yt_sum(n)和yt_sum(n-1)的关系
yt_sum(n): 1+2+3+...+n-1+n
yt_sum(n-1): 1+2+3+...n-1
yt_sum(n) = yt_sum(n-1)+n
"""
return yt_sum(n-1)+n
print(yt_sum(4))
print(yt_sum(100))
运行结果:
10
5050
练习: 求斐波那契数列第n个数
ef sequence(n):
# 1.找临界值
if n == 1 or n == 2:
return 1
# 2. f(n)和f(n-1)
"""
f(n) = f(n-1)+f(n-2)
"""
return sequence(n-1)+sequence(n-2)
print(sequence(5))
运行结果
5
4.循环能做的事情不能使用递归做!
例如:
sum1 = 0
for x in range(10001):
sum1 += x
print(sum1)
def yt_sum(n):
if n == 1:
return 1
return yt_sum(n-1)+n
print(yt_sum(100))
运行结果:
50005000
5050
三、模块
1.什么是模块
在python中一个py文件就是一个模块
a.系统模块(标准库) - python系统提供的模块(安装解释器的时候已经导入到解释器中了,使用的时候在代码中直接导入)
random模块 - 提供随机数
math模块 - 提供数学运算
json库 - 提供json数据相关操作
re模块 - 提供正则表达式相关操作
socket模块 - 提供python套接字编程
time模块 - 提供和时间相关的操作
threading模块 - 提供和线程相关的操作
...
b.自定义模块 - 程序员自己创建的py文件
自己写的模块
别人写的模块 - 第三方库 (需要先下载到解释器中,然后才能再代码中导入)
标准库和第三库一般是通过模块提供变量、函数、类
2.怎么使用模块
import 模块名 - 在程序中直接导入指定的模块, 导入后可以使用模块中所有的全局变量(包含了变量、函数和类)
导入后通过"模块名.变量"来使用模块中的内容
from 模块名 import 变量1, 变量2 - 在程序中导入指定的模块,导入后只能使用import后面的变量
导入后直接使用变量,不用在前面加'模块名.'
from 模块名 import * - 在程序中直接导入指定的模块, 导入后可以使用模块中所有的全局变量(包含了变量、函数和类)
导入后直接使用变量,不用在前面加'模块名.'
3.导入模块的实质
a.不管是使用 import 还是 from-import ,导入模块的时候都会执行模块中的所有代码
b.python中,一个模块不会重复导入多次。因为导入的时候系统会自动检查之前有没有导入这个模块
4.怎么阻止模块中的内容被其它模块执行
将不希望被其它模块执行的代码放在 if 语句中,如果希望被其它模块使用的代码就放在 if 语句代码外
写在这个 if 语句中的代码不会被别的模块执行:
if __name__ == '__main__':
main()
原理:每个模块都有一个 name 属性,代表模块名。默认情况下它的值是 py 文件的文件名。
当前模块正在被执行()的时候,
5.重命名
导入模块的时候,可以对模块或者模块中的内容重新命名。
import 模块名 as 新模块名
from 模块名 import 变量名1 as 新变量名2, 变量名2 as 新变量名2
四、迭代器
1.什么是迭代器(iter)
是python提供的容器型数据类型
获取迭代器中的元素的时候,只能从前往后一个一个的取,而且取了之后这个元素在迭代器中就不存在了。
2.迭代器的字面量
迭代器没有指定格式的字面量,迭代器作为容器,里面的元素只能通过其他序列转换而成,或者通过生成器生成。
迭代器里面的数据可以是任何数据类型。
iter1 = iter('halo') -----将字符串转换成迭代器,迭代器中的元素就是字符串中的每个元素
iter2 = iter([123, 'adc'], (10, 20), [30, 40]) -----将列表转换成迭代器,迭代器里面的元素就是列表里面的所有元素。
3.获取元素
迭代器里面的元素只支持查,不支持增删改。
迭代器只能通过 next 函数获取单个元素,或者通过 for-in 遍历,一个一个获取每一个元素。
已经获取过的元素,在迭代器里面就不存在了。
a.
next(迭代器) -----获取迭代器里最新(顶层)的数据
如果取完了迭代器里面的数据后还取,会报错。
b.
for i in 迭代器:
print(i)
效果和 next 效果一样,元素还会从迭代器中取出。
五、生成器
1.什么是生成器
生成器就是迭代器,迭代器不一定是生成器。
2.生成器怎么产生元素
调用一个带有 yield 关键字的函数,就能得到一个生成器。
例如:
# 不带 yield 的函数,调用的时候,会执行函数体,并且获取返回值。
def func1():
print('===')
return 100
print(func1)
# 带 yield 的函数,调用的时候,不会执行函数体,也不会获取返回值,而是生成一个生成器(函数调用表达式就是一个生成器)。
# 这个生成器中的元素就是 yield 关键字后面的值(元素)
def func2():
print('===')
return 100
yield
print(func2)
运行结果:
===
100
<generator object func2 at 0x000001350B0A5938>
3.生成器的元素
生成器中的元素也是通过 next 或者 for-in
生成器获取元素的时候,实质就是去执行生成器对应的函数,每次执行到 yield 语句为止,
并且会将 yield 后面的值作为当次获取到的元素, 保留当次执行到 yield 的位置。
下次获取元素的时候,会接着上层结束的位置,往后执行,直到遇到下个 yield 为止。以此类推,直到函数结束。
如果执行到函数结束都没有遇到 yield 那么就会报‘stopiterator’错误。
例如:
def func3():
print('…………')
yield 1000
print('!!!!!!')
yield 100
gen1 = func3() # gen1 就是一个生成器
print(gen1)
print('打印', next(gen1))
print('打印', next(gen1))
运行结果:
<generator object func3 at 0x000001350B0A5938>
…………
打印 1000
!!!!!!
打印 100
例如:
运行结果: