PYTHON1.day09
分类:
IT文章
•
2022-11-15 00:32:25
day08 回顾:
两个容器:
集合set 和 固定集合 frozenset
可变 不可变
集合的创建:
构造函数:
set()
set(range(10)))
字面值:
{1, 2, 3, 4}
集合推导式:
{x ** 2 for x in range(1, 10)}
固定集合的创建:
构造函数:
frozenset()
frozenset(range(10))
集合的运算:
&交集 |并集 ^对称补集
-补集 <子集 >超集 ==相等 !=不等
<=子集或相等 >= 超集或相等
in / not in
集合的方法:
S.add(x) 增加
S.remove(x) 删除
S.discard(x) 删除(但不提示错误)
S.clear()
S.pop() 删除随机元素
S.copy()
能用容器类的函数
len(x) min(x) max(x) .....
函数 function
函数是面向过程编程的最小单位
两条语句:
def 语句
语法:
def 函数名(形参变量1, 形参变量2, ....):
语句块
作用:
创建函数, 用函数名绑定这个函数
调用表达式:
函数名(实参1, 实参2, ....)
return 语句
作用:
结束当前函数的执行,返回到调用此函数的地方
格式:
return [表达式]
day09 笔记:
python函数的参数传递(把数据给函数)
传递方式:
位置传参
序列传参
关键字传参
字典关键字传参
位置传参:
实际参数(实参)的对应关系与形式参数(形参)的对应关系是按位置
来依次对应的
示意:
def mymin(a, b, c):
pass
mymin( 1, 2, 3)
说明:
实际参数和形式参数通过位置进行传递和匹配
实际参数的个数必须与形式参数的个数相同
示例见:
positional_give_args.py
1 # positional_give_args.py
2
3
4 # 此示例示意位置传参
5 def myfun1(a, b, c):
6 '''这是一个函数传参的示例'''
7 print("a的值是:", a)
8 print("b的值是:", b)
9 print("c的值是:", c)
10
11 myfun1(1, 2, 3) # 1-->a 2-->b 3-->c
12 myfun1(4, 5, 6)
13
14
15
16
序列传参 序列传参是指在函数调用过程中,用*将序列拆解后按位置进行传递的
传参方式
示例见:
sequence_give_args.py
1
2
3 # 此示例示意序列传参
4 def myfun1(a, b, c):
5 '''这是一个函数传参的示例'''
6 print("a的值是:", a)
7 print("b的值是:", b)
8 print("c的值是:", c)
9
10 L1 = [11, 22, 33]
11 t2 = (100, 200, 300)
12 s3 = "ABC"
13
14 myfun1(L1[0], L1[1], L1[2]) # L1[0](将11)---> a, L1[1]--->b, ...
15 myfun1(*L1) # 等同于myfunc(L1[0], L1[1], L1[2])
16 myfun1(*t2)
17 myfun1(*s3)
18
19
20
说明:
序列传参时,序列拆解的位置将与形参一一对应
关键字传参:
关键字传参是指传参时,按着形参的名称给形参赋值
实参和形参按名称进行匹配
示例见:
keywords_give_args.py
1
2
3 # 此示例示意 关键字 传参
4 def myfun1(a, b, c):
5 '''这是一个函数传参的示例'''
6 print("a的值是:", a)
7 print("b的值是:", b)
8 print("c的值是:", c)
9
10 myfun1(c=33, b=22, a=11)
11 myfun1(b=2, a=1, c=3)
12
13
说明:
实参和形参接形参名进行匹配,可以不按位置进行匹配
字典关键字传参:
是指实参为字典,将字典用**拆解后进行关键字传参的传参方式
示例见:
dict_keyword_give_args.py
1
2
3 # 此示例示意 字典关键字 传参
4 def myfun1(a, b, c):
5 '''这是一个函数传参的示例'''
6 print("a的值是:", a)
7 print("b的值是:", b)
8 print("c的值是:", c)
9
10 d1 = {'c': 33, 'a': 11, 'b': 22}
11 myfun1(c=d1['c'], a=d1['a'], b=d1['b']) # 33--->c , 11--->a ...
12
13 myfun1(**d1) # 拆解字典,再按关键字传参方式传递
14
15
16
说明:
字典的键名和形参名必须一致
字典的键名必须为符合标识符命名规则的字符串
字典的键名要在形参中存在
练习:
已知有列表:
L = [1, 2, True, None, 3.14]
调用print函数,打印用'#'号分隔的文字信息到终端上
print(....) # 打印 1#2#True#None#3.14
1 # 练习:
2 # 已知有列表:
3 # L = [1, 2, True, None, 3.14]
4 # 调用print函数,打印用'#'号分隔的文字信息到终端上
5 # print(....) # 打印 1#2#True#None#3.14
6
7
8
9 L = [1, 2, True, None, 3.14]
10
11 print(*L, sep="#") # 打印 1#2#True#None#3.14
12 # 等同于print(1, 2, True, None, 3.14, sep='#')
13
14
函数的综合传参:
1. 函数的传参方式,在能确定形参能唯一匹配到相应实参的情况
下可以任意组合
2. 函数的位置传参要先于关键字传参
示例:
def myfun1(a, b, c):
pass
myfun1(100, c=300, b=200) # 正确
myfun1(c=300,b=200, 100) # 错的
myfun1(100, *[200, 300]) # 正确
myfun1(*[100, 200], 300) # 正确
myfun1(100, *[200], 300) # 正确
myfun1(100, **{'c':300, 'b':200}) # 正确
myfun1(**{'c':300, 'b':200}, a=100) # 正确
可变 和不可变类型的容器作为实参传递的区别:
可变类型的实参作为参数传递时,在函数内部可以改变容器内的数据
示例见:
list_as_args.py
list_as_args2.py
1 # list_as_args.py
2
3 # 此示例示意,当函数的实参为可变数据类型时,在函数内部可以改为
4 # 容器的内容
5
6 L = [1, 2, 3, 4]
7 t = (1.1, 2.2, 3.3, 4.4)
8
9 def append_5(x):
10 # x.append(5)
11 x += (5,)
12 print('x=', x) # 1.1, 2.2, 3.3, 4.4, 5
13
14 append_5(L)
15 print(L) # [1, 2, 3, 4, 5]
16
17 append_5(t)
18 print(t) # (1.1, 2.2, 3.3, 4.4)
19
20
21
22
1
1 # list_as_args2.py
2
3
4 # 写一个函数,此函数读取用户输入的数据,最后保存于全局变量的列表
5 # L中, 当用户输入小于零的数时结束输入
6 L = []
7 def input_number(L1):
8 while True:
9 x = int(input('请输入:'))
10 if x < 0:
11 break
12 L1.append(x)
13
14 input_number(L)
15 print(L)
16 input_number(L)
17 print(L)
18
19
20
21
22
23
24
2
----- 以下讲函数的定义(创建函数的def语句的形参列表)----
函数的缺省参数:
语法:
def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ...):
语句块
示例见:
default_args.py
1 # default_args.py
2
3
4 def info(name, age=1, address='不详'):
5 print(name,'今年', age, '岁,家庭住址:', address)
6
7 info("魏明择", 35, '北京市朝阳区')
8 info("tarena", 15)
9 info("小飞")
10
default_args
说明:
缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其
右侧的所有参数都必须有缺省参数,如:
def test_fn(a, b=10, c): 是错的
缺省参数可以有0个,1个或多个,甚至全部都有缺省参数
示例:
def fn(a, b=10, c): # 错误
pass
def fn(a=0, b=10, c=20): # 这是对的
pass
练习:
写一个函数myadd,此函数可以计算两个数,三个数及四个数的和
def myadd(...):
...
print(myadd(10, 20)) # 30
print(myadd(100, 200, 300)) # 600
print(myadd(1, 2, 3, 4)) # 10
1 # 练习:
2 # 写一个函数myadd,此函数可以计算两个数,三个数及四个数的和
3 # def myadd(...):
4 # ...
5
6 # print(myadd(10, 20)) # 30
7 # print(myadd(100, 200, 300)) # 600
8 # print(myadd(1, 2, 3, 4)) # 10
9
10
11 def myadd(a, b, c=0, d=0):
12 return a + b + c + d
13
14 print(myadd(10, 20)) # 30
15 print(myadd(100, 200, 300)) # 600
16 print(myadd(1, 2, 3, 4)) # 10
17
18
函数形参的定义方式:
1. 位置形参
2. 星号元组形参
3. 命名关键字形参
4. 双星号字典形参
位置形参
语法:
def 函数名(形参名1, 形参名2, ...):
语句块
星号元组形参:
语法:
def 函数名(*元组形参名):
语句块
作用:
收集多余的位置传参
说明:
在一个函数定义中元组形参名最多只能有一个,一般命名为'args'
示例见:
star_tuple_args.py
练习:
写一个函数 mysum 可以传入任意个数字实参,返回所有实参的和
def mysum(*args):
...
print(mysum(1, 2, 3, 4)) # 10
print(mysum(1, 3, 5, 7, 9)) # 25
1 # 练习:
2 # 写一个函数 mysum 可以传入任意个数字实参,返回所有实参的和
3 # def mysum(*args):
4 # ...
5
6 # print(mysum(1, 2, 3, 4)) # 10
7 # print(mysum(1, 3, 5, 7, 9)) # 25
8
9
10 # 方法1
11 # def mysum(*args):
12 # s = 0
13 # for x in args:
14 # s += x
15 # return s
16
17 # 方法2
18 def mysum(*args):
19 return sum(args)
20
21 print(mysum(1, 2, 3, 4)) # 10
22 print(mysum(1, 3, 5, 7, 9)) # 25
23
24
sun
命名关键字形参
语法:
def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):
语句块
或
def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ..):
语句块
作用:
强制所有的参数都必须用关键字传参或字典关键了传参
示例见:
named_keyword_args.py
named_keyword_args2.py
1 # named_keyword_args.py
2
3
4 # 此示例示意在函数形参中定义命名关键字形参,强制让函数调用
5 # 使用命名关键字传参:
6
7 def func1(a, b, *, c, d):
8 print(a, b, c, d)
9
10 # func1(1, 2, 3, 4) # 报错
11 func1(1, 2, c=30, d=40)
12 func1(a=10, b=20, c=30, d=40)
13
14
1
1 # named_keyword_args.py
2
3
4 # 此示例示意在函数形参中定义命名关键字形参,强制让函数调用
5 # 使用命名关键字传参:
6
7 def func1(a, b, *args, c, d):
8 print(a, b, args, c, d)
9
10 # func1(1, 2, 3, 4) # 报错
11 func1(1, 2, c=30, d=40)
12 func1(a=10, b=20, c=30, d=40)
13 func1(1, 2, 3, 4, d=400, c=300)
14
15 func1(*"ABCDEFG", **{'c':999, 'd':888})
16
17
18
2
双星号字典形参
语法:
def 函数名(**字典形参名):
语句块
作用:
收集多余的关键字传参
说明:
字典形参名一般命名为'kwargs'
一个函数内字典形参最多只能有一个
示例见:
star_dict_args.py
1 # star_dict_args.py
2
3 # 此示例示意用双星号字典形参接收多余的关键字传参
4
5 def func(**kwargs):
6 print("关键字传参的个数是:", len(kwargs))
7 print("kwargs=", kwargs)
8
9 func(name='weimingze', age=35, address='北京市朝阳区')
10 func(a=1, b=2)
11
1
1 # star_tuple_args.py
2
3 # 此示例示意星号元组形参的定义和使用
4
5 def func(*args):
6 print("实参个数是:", len(args))
7 print('args=', args)
8
9 func(1, 2, 3, 4)
10 func(5, 6, 7, 8, 'A', 'B', 'C', 'D')
11 func()
12
2
函数的参数说明:
位置形参,缺省参数,星号元组形参,双星号字典形参可以混合使用
函数参数自左至右的顺序为:
1. 位置形参
2. 星号元组形参
3. 命名关键字形参
4. 双星号字典形参
示例:
def fn(a, b=20, *args, c=30, d=40, **kwargs):
pass
fn(1)
fn(100, 200, 300, 400, c='C', d='D', e='E')
练习:
已知内建函数max帮助文档为:
max(...)
max(iterable) -> value
max(arg1, arg2, *args) -> value
仿造 max写一个mymax函数,功能与max完全相同
(要求不允许调用max)
测试程序如下:
print(mymax([6, 8, 3, 5])) # 8
print(mymax(100, 200)) # 200
print(mymax(1, 3, 5, 9, 7)) # 9
1 # 练习:
2 # 已知内建函数max帮助文档为:
3 # max(...)
4 # max(iterable) -> value
5 # max(arg1, arg2, *args) -> value
6 # 仿造 max写一个mymax函数,功能与max完全相同
7 # (要求不允许调用max)
8 # 测试程序如下:
9 # print(mymax([6, 8, 3, 5])) # 8
10 # print(mymax(100, 200)) # 200
11 # print(mymax(1, 3, 5, 9, 7)) # 9
12
13
14 # def mymax(a, *args):
15 def mymax(*args):
16 # print("args=", args)
17 if len(args) == 1: # 判断是否是一个可迭代参数的情况
18 L = args[0] # 一定绑定一个可迭代对象
19 zuida = L[0] # 假设第一个元素最大
20 for x in L:
21 if x > zuida:
22 zuida = x
23 return zuida
24 else: # 否则有多个参数的情况
25 zuida = args[0]
26 for x in args:
27 if x > zuida:
28 zuida = x
29 return zuida
30
31
32 print(mymax([6, 8, 3, 5])) # 8
33 print(mymax(100, 200)) # 200
34 print(mymax(1, 3, 5, 9, 7)) # 9
35
36
37
38
max
1 # 练习:
2 # 已知内建函数max帮助文档为:
3 # max(...)
4 # max(iterable) -> value
5 # max(arg1, arg2, *args) -> value
6 # 仿造 max写一个mymax函数,功能与max完全相同
7 # (要求不允许调用max)
8 # 测试程序如下:
9 # print(mymax([6, 8, 3, 5])) # 8
10 # print(mymax(100, 200)) # 200
11 # print(mymax(1, 3, 5, 9, 7)) # 9
12
13
14 def mymax(a, *args):
15 if len(args) == 0: # 判断是否是一个可迭代参数的情况
16 L = a # 一定绑定一个可迭代对象
17 zuida = L[0] # 假设第一个元素最大
18 for x in L:
19 if x > zuida:
20 zuida = x
21 return zuida
22 else: # 否则有多个参数的情况
23 zuida = a
24 for x in args:
25 if x > zuida:
26 zuida = x
27 return zuida
28
29
30 print(mymax([6, 8, 3, 5])) # 8
31 print(mymax(100, 200)) # 200
32 print(mymax(1, 3, 5, 9, 7)) # 9
33
34
35
36
max2
全局变量 和 局部变量
局部变量 local varible:
定义在函数内部的变量称为局部变量(函数的形参也是局部变量)
局部变量只能在函数内部使用
局部变量在函数调用时才能够被创建,在函数调用之后会自动销毁
当有同名的全局变量和局部变量时,优先访问局部变量
全局变量 global variable:
定义在函数外部,模块内部的变量称为全局变量
全局变量,所有函数都可以直接访问(但函数内不能将其直接赋值)
局部变量说明:
在函数内部赋值语句不会对全局变量造成影响
局部变量只能在其被声明的函数内部访问,而全局变量可以在整数模
块范围内访问
示例见:
global_local.py
1 # global_local.py
2
3 # 此示例示意全局变量的定义和局部变量的定义
4 a = 100
5 b = 200
6 c = 9999999
7 def fx(c):
8 a = 1 # 创建局部变量,并非改变全局变量
9 d = 400
10 print(a, b, c, d)
11
12 fx(300)
13 print('a=', a) # 100
14 print('b=', b)
15 print('c=', c)
globals 和 locals 函数:
globals() 返回当前全局作用域内变量的字典
locals() 返回当前局部作用域内变量的字典
示例见:
globals_and_locals.py
1 # globals_and_locals.py
2
3
4 # 此示例示意globals 和 locals函数的使用方法
5 a = 1
6 b = 2
7 c = 3
8 def fn(c, d):
9 e = 300
10 # 此处有多少个局部变量?
11 print("locals()返回:", locals())
12 # 此处有多少个全局变量?
13 print("globals() 返回:", globals())
14 print(c) # 100
15 print(globals()['c']) # 3
16
17
18 fn(100, 200)
19
练习:
1. 算出 100 ~ 999 以内的水仙花数(Narcissistic number)
水仙花数是指百位的3次方加上十位的3次方加上个位的3次方
等于原数的整数
例如: 153 = 1**3 + 5**3 + 3**3
答案: 153, 370, ...
1 # 1. 算出 100 ~ 999 以内的水仙花数(Narcissistic number)
2 # 水仙花数是指百位的3次方加上十位的3次方加上个位的3次方
3 # 等于原数的整数
4 # 例如: 153 = 1**3 + 5**3 + 3**3
5 # 答案: 153, 370, ...
6
7 # 方法1
8 # for x in range(100, 1000):
9 # # 拆出百位,十位,个位
10 # bai = x // 100 # 百位
11 # shi = x % 100 // 10 # 十位
12 # ge = x % 10 # 个位
13 # if x == bai ** 3 + shi ** 3 + ge ** 3:
14 # print(x) # 满足条件的水仙花数
15
16 # 方法2, 将数字转为字符串
17 # for x in range(100, 1000):
18 # s = str(x)
19 # bai = int(s[0])
20 # shi = int(s[1])
21 # ge = int(s[2])
22 # if x == bai ** 3 + shi ** 3 + ge ** 3:
23 # print(x) # 满足条件的水仙花数
24
25 # 方法3
26 for bai in range(1, 10):
27 for shi in range(0, 10):
28 for ge in range(10):
29 # print(bai, shi, ge)
30 x = bai * 100 + shi * 10 + ge
31 if x == bai ** 3 + shi ** 3 + ge ** 3:
32 print(x)
2. 完全数:
1 + 2 + 3 = 6 (6为完全数)
1, 2, 3都为6的因数(能被一个数x整除的数为y,则y为x的因数)
1 x 6 = 6
2 x 3 = 6
完全数是指除自身以外的所有因数之和相加等于自身的数
求4~5个完全数,并打印
答案:
6
28
496
...
1 # 2. 完全数:
2 # 1 + 2 + 3 = 6 (6为完全数)
3 # 1, 2, 3都为6的因数(能被一个数x整除的数为y,则y为x的因数)
4 # 1 x 6 = 6
5 # 2 x 3 = 6
6 # 完全数是指除自身以外的所有因数之和相加等于自身的数
7 # 求4~5个完全数,并打印
8 # 答案:
9 # 6
10 # 28
11 # 496
12 # ...
13
14 def is_perfect_number(x):
15 '''此函数判断x是否为完全数,如果是返回True,否则返回False'''
16 L = [] # 创建一个列表,用来存放x所有的因数
17 for i in range(1, x):
18 if x % i == 0: # 整除了,i则一定是x的因数
19 L.append(i)
20 if sum(L) == x: # 是完全数
21 return True
22 return False
23
24 def main():
25 i = 2
26 while True:
27 # 如果i是完全数,则打印i的值
28 if is_perfect_number(i):
29 print(i)
30
31 i += 1
32
33 main()
34
3. 写一个myrange()函数,参数可以传1~3个,实际意义同range函数
规则相同,此函数返回符合range(...) 函数规则的列表
如:
L = myrange(4)
print(L) # [0, 1, 2, 3]
L = myrange(4, 6)
print(L) # [4, 5]
L = myrange(1, 10, 3)
print(L) # [1, 4, 7]
1 # 3. 写一个myrange()函数,参数可以传1~3个,实际意义同range函数
2 # 规则相同,此函数返回符合range(...) 函数规则的列表
3 # 如:
4 # L = myrange(4)
5 # print(L) # [0, 1, 2, 3]
6 # L = myrange(4, 6)
7 # print(L) # [4, 5]
8 # L = myrange(1, 10, 3)
9 # print(L) # [1, 4, 7]
10
11
12 def myrange(start, stop=None, step=None):
13 if stop is None: # if not stop:
14 stop = start
15 start = 0
16 if step is None:
17 step = 1
18 # 开始,结束和步长都已确定
19 # return [x for x in range(start, stop, step)]
20 if step > 0: # 正向
21 L = []
22 while start < stop:
23 L.append(start)
24 start += step
25 return L
26 elif step < 0:
27 L = []
28 while start > stop:
29 L.append(start)
30 start += step
31 return L
32
33 L = myrange(4)
34 print(L) # [0, 1, 2, 3]
35 L = myrange(4, 6)
36 print(L) # [4, 5]
37 L = myrange(1, 10, 3)
38 print(L) # [1, 4, 7]
39
40 L2 = myrange(10, 0, -2)
41 print(L2)
42
43
44
1
2 # 3. 改写之前的学生信息管理程序:
3 # 用两个函数来封装功能的代码块
4 # 函数1: input_student() # 返回学生信息字典的列表
5 # 函数2: output_student(L) # 打印学生信息的表格
6
7 def input_student():
8 L = [] # 创建一个列表,准备存放学生数据的字典
9 while True:
10 n = input("请输入姓名: ")
11 if not n: # 如果用户输入空字符串就结束输入
12 break
13 a = int(input("请输入年龄: "))
14 s = int(input("请输入成绩: "))
15 d = {} # 一定要每次都创建一个新的字典
16 d['name'] = n
17 d['age'] = a
18 d['score'] = s
19 L.append(d) # 把d加入列表中L
20 return L
21
22 def output_student(L):
23 print("+---------------+----------+----------+")
24 print("| 姓名 | 年龄 | 成绩 |")
25 print("+---------------+----------+----------+")
26 for d in L:
27 name = d['name']
28 age = str(d['age']) # 转为字符串
29 score = str(d['score']) # 转为字符串
30 print("|%s|%s|%s|" % (name.center(15),
31 age.center(10),
32 score.center(10)))
33 print("+---------------+----------+----------+")
34
35
36 # infos = input_student()
37 # print(infos) # 打印列表[{...}, {...}]
38 # output_student(infos) # 根据实参infos打印表格
39
40 def main():
41 infos = [] # 此列表用于保存学生数据
42 while True:
43 print(" 1) 添加学生信息")
44 print(" 2) 显示学生信息")
45 print(" q) 退出")
46 s = input("请选择: ")
47 if s == '1':
48 infos += input_student()
49 elif s == '2':
50 output_student(infos)
51 elif s == 'q':
52 break
53
54
55 main()
56
student