基本信息
源码名称:python学习笔记--达内
源码大小:2.77M
文件格式:.docx
开发语言:Python
更新时间:2020-07-11
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
下载后,请改成txt后缀名打开即可。
2019--8--31
x='123'
y=x*2----y='123123'
x=3
x*='123'---x='123123123'
练习:
写一个程序,打印一个高度为4的矩形方框,要求输入一个整数,此整数代表矩形的宽度,
输出此矩形如:
请输入宽度:10
打印如下:
##########
# #
# #
##########
w=int(input("请输入矩形的宽度:"))
s1 = w * '#'
s2 ='#' (w-2)*' ' '#'
print(s1)
print(s2)
print(s2)
print(s1)
字符串的比较运算
运算符:
> >= < <= == !=
示例:
'A' < 'B' #True
'B' < 'a' #True
'ABC'>'AB' #True
'AD' <'ABC #False
'ABC' == 'abc' #False
int / not in 运算符
作用
in用于序列,字典,集合中,用于判断某个值是否存在容器中,如果存在则返回True,否则返回False。
格式
对象in容器
示例:
s = 'welcome to tarena!'
'to' in s # True
'weimingze' in s #False
字符串的索引操作
python 字符串str是不可以改变的字符序列
索引语法
字符串[整数表达式]
说明
python序列都可以用索引(index)
来访问序列中的对象(元素)
python序列的正向索引是从0开始的,第二个索引为1,最后一个索引为len(s) -1
python序列的反向索引是从-1开始的,-1代表最后一个,-2代表倒数第二个,第一个是-len(s)
示例:
s='ABCDE'
print(s[0]) #A
print(s[4]) #E
切片 slice
作用:
从字符串序列中取出一部分相应的元素重新组成一个字符串
语法:
字符串[(开始索引b):(结束索引e)(:(不长s))]
注:()内括起的部分代表可以省略
说明:
1、开始索引是切片开始切下的位置0代表第一个元素,-1代表最后一个元素。
2、结束索引是切片的终止索引(但不包含终止索引)
3、步长是切片每次获取完当前索引后移动的方向和偏移量
1)没有步长,相当于取值完成后向后移动一个索引的位置(默认为1)
2)当步长为正整数时,取正向切片:步长默认为1,开始索引默认值为0,结束索引
默认值为len(s)
3)当步长为负整数时,取反向切片:反向切片时,默认的起始位置为最后一个元素,默认终止位置为第一个元素的前一个位置。
示例:
A B C D E
0 1 2 3 4
-5 -4 -3 -2 -1
>>> s='ABCDE'
>>> s[1:1] ''
>>> s[1:2] 'B'
>>> s[1:] 'BCDE'
>>> s 'ABCDE'
>>> s[:2] 'AB'
>>> s[:] 'ABCDE'
>>> s[4:2] ''
>>> s[4:] 'E'
>>> s[2:10000] 'CDE' #开始索引/结束索引可以越界
>>> s[1:4:2] 'BD'
>>> s[::2] 'ACE'
>>> s[::3] 'AD'
>>> s[1::2] 'BD'
>>> s[::-1] 'EDCBA'
>>> s[::-2] 'ECA'
>>> s[4:0:-2] 'EC'
练习:
1、写一个程序,输入一个字符串,把字符串的第一个字符和最后一个字符去掉,打印出处理后的字符串。
个人解答如下:
s=input("请输入一个字符串:")
l=len(s)
s1=s[1:(l-1)]
print("去掉字符串第一个字符和最后一个字符后为:" s1)
老师解答
s1=s[1:-1]
2、输入任意字符串,判断这个字符串是否是回文,回文是指中心对称的文字,如:上海自来水来自海上
ABCCBA
12321
个人解答如下:
s=input("请输入一个字符串:")
l=len(s)
n=l//2
if l%2==0:
s1=s[:n]
s2=s[:(n-1):-1]
if s1==s2:
print("你好,这是一个回文字符串哦!")
else:
print("你好,这不是一个回文字符串!")
else:
s1=s[:(n 1)]
s2=s[:(n-1):-1]
if s1==s2:
print("你好,这是一个回文字符串哦!")
else:
print("你好,这不是一个回文字符串!")
老师解答如下:
s2=s[::-1]
if s==s2:
print(s,'是回文')
else:
print(s,'不是回文')
python3中常用的序列函数:
len(seq) 返回序列的长度
max(x) 返回序列的最大值元素
min(x) 返回序列的最小值元素
示例:
s="ABCD"
print(len(s)) # 4
print(max(s)) # D
print(min(x)) # A
>>> s='a b\ncd'
>>> len(s)
6
字符串编码转换函数
ord(c)返回一个字符串的Unicode编码值
chr(i)返回i这个值所对应的字符
示例:
print(ord('A')) #65
print(ord('中')) #20013
print(chr(20013)) #'中'
练习:
1、写一个程序,输入一段字符串,如果字符串不为空,则把第一个字符的编码打印出来。
s=input("请输入一段字符串:")
if s!=' ':
print(ord(s[0]))
2、写一个程序,输入一个整数值(0~65535),打印出这个值所对应的字符。
s=int(input("请输入一个整数:"))
print(chr(s))
整数转换为字符串函数
hex(i) 将整数转换为十六进制的字符串
oct(i) 将整数转换为八进制字符串
bin(i) 将整数转换为二进制字符串
>>> hex(10) '0xa'
>>> oct(8) '0o10'
>>> bin(4) '0b100'
字符串的构造(创建)函数 str
str(obj='') 将对象转换为字符串
示例:
s=123
print(str(s) '456') # 123456
练习:
1、用字符串*运算符打印三角形,要求输入一个整数,此整数代表此三角形离左侧的字节数,请输入左侧的距离:3,则打印
*
***
*****
*******
2、输入三行文字,让这三行文字在一个方框居中显示如输入(不要输入中文):hello tarena! my name is weimingze python
显示如下
----------------------
| hello tarena! |
|my name is weimingze |
| python |
----------------------
常见的字符串方法:
字符串方法的调用语法
对象.方法名(方法传参)
注:
方法的调用属于表达式,通常可以返回一个值或None
示例:
'abc'.isalpha() #正确
>>> 123.isalpha()
File "<stdin>", line 1
123.isalpha()
^
SyntaxError: invalid syntax
>>> '123'.isalpha()
False
>>> 'abc'.isalpha()
True
练习:
输入一个字符串
1、判断您输入的字符串有几个空格
2、将原字符串的左右空白字符去掉,打印出有效字符的长度
3、判断您输入的是否是数字
s=intput("请输入一个字符串:")
print("您输入的字符串有",s.count(' '),"个空格")
s2=s.strip()
print("有效字符的个数是:",len(s2))
if s2.isdigit():
print("您输入数的是数字")
else:
print("您输入的不是数字")
字符串格式表达式
运算符:
%
作用:
生成一定格式的字符串
语法:
格式字符串%参数值
格式字符串%(参数值1,参数值2,...)
格式字符串中的%为占位符,占位符的位置将用参数值替换
示例:
>>> 'name:%s,age:%d' % ('zhangsan',24)
'name:zhangsan,age:24'
fmt="姓名:_%s_,年龄:_%d_"
name=input("请输入姓名:")
age=int(input("请输入年龄:"))
s=fmt%(name,age)
print(s)
D:\code>python lianxi55.py
请输入姓名:zhouwei
请输入年龄:31
姓名:_zhouwei_,年龄:_31_
>>> 'aaa%dbbb' % 10
'aaa10bbb'
格式化字符串中的占位符合类型码
占位符 意义
%s 字符串,使用str函数转换
%r 字符串,使用repr函数转换
%c 整数转为单个字符
%d 十进制整数
%o 八进制整数
%x 十六进制整数(a-f小写)
%X 十六进制整数(A-F大写)
%e 指数形浮点数(e小写)如:2.9e 10
%E 指数形浮点数(E大写)如:2.9E 10
%f,%F 浮点十进制形式
%g,%G 十进制形式浮点数或指数浮点数自动转换
%% 等同于一个%字符
占位符和类型码之间的格式语法
% [格式语法] 类型码
格式语法:
- 左对齐
显示正号
0 补零
宽度(整数)
宽度.精度(整数)
示例:
'%10d' % 123 #' 123'
'%-10d' % 123 #'123 '
'%10s' % 'abc' #' abc'
'%-5x' % 'abc' #'abc '
'05d' % 123 #'00123'
'%07.3f' % 3.1415926 #'003.141'
练习:
输入三行文字,让这些文字一次以20字符的宽度右对齐
输出如:
请输入第一行:hello world
请输入第二行:abcd
请输入第三行:a
输出结果为:
hello world
abcd
a
做完上面的题后再思考:
能否以最长字符串的长度进行右对齐显示(左侧填充空格)
s1=input("请输入第1行:")
s2=input("请输入第2行:")
s3=input("请输入第3行:")
#方法1
print('%20s'%s1)
print('%20s'%s2)
print('%20s'%s3)
#方法2
m=max(len(s1),len(s2),len(s3))
print('最大长度是:',m)
print(' '*(m-len(s1)) s1)
print(' '*(m-len(s2)) s2)
print(' '*(m-len(s3)) s3)
#方法3
fmt='%%%ds' % m #生成一个含有占位符的字符串
print('fmt=',fmt)
print(fmt%s1)
print(fmt%s2)
print(fmt%s3)
D:\code>python lianxi6
请输入第1行:hello wor
请输入第2行:abcd
请输入第3行:a
hello world
abcd
a
最大长度是: 11
hello world
abcd
a
fmt= %11s
hello world
abcd
a
循环语句
while语句
作用:
根据一定条件,重复的执行一条语句或多条语句
语法:
while 真值表达式:
语句块
else:
语句块
示例:
n=int(input("请输入一个数:"))
i=1
while i<n:
print("hello world")
i =1
else:
print("条件不满足,循环结束!")
#方法2,直接用变量n来控制循环次数
while 1<n:
print("hello world")
n-=1
D:\code>python lianxi7.py
hello world
hello world
hello world
hello world
条件不满足,循环结束!
示例:
(1)用while语句打印1-20的整数(包含20)
i=1
while i<=20:
print(i)
i =1
(2)输入一个整数,用end变量绑定,打印出1-end的所有整数(包含end)
end=int(input("请输入一个整数:"))
i=1
while i<=end:
print(i)
i =1
(3)写程序,输入2个整数,第一个用begin绑定,第二个用end变量绑定,打印出begin
-end的所有整数。
begin=int(input("请输入第一个整数:"))
end=int(input("请输入第二个整数:"))
while begin<=end:
print(begin)
begin =1
(4)打印1-20整数,在一行显示,每个数字空格隔开
i=1
while i<=20:
print(i,end=' ')
i =1
(5)打印1-20整数,每行5个,打印四行
i=1
while i<=20:
print(i,end=' ')
if i%5==0
i =1
print()
(6)写程序,计算1 2 3 ...100的和
i=1
s=0
while i<=100:
s =i
i =1
print("1-100的和是:",s)
(7)用while打印直角三角形,输入一个数表示宽度和高度
*
**
***
****
n=int(input("请输入第一个整数:"))
i=1
while i<=n:
print('*' * i)
i =1
while语句嵌套
while语句本身是语句,和其他语句一样,可以放在其它复合语句的内部
while嵌套示意
while 真值表达式:
...
while 真值表达式2:
...
else:
...
else:
...
break语句
作用:
用于循环语句(while,for语句)中,用来终止当前循环语句的执行。
说明:
(1)当break语句执行后,此循环语句break之后的语句将不再执行。
(2)break语句通常和if语句组合使用
(3)break语句终止循环时,循环语句的else子句的语句将不会执行。
(4)break语句只能终止当前循环语句的执行,如果有循环嵌套时,不会跳出嵌套的外重循环。
(5)break语句只能在循环语句(while或for语句)内部使用。
死循环
死循环是指循环条件一直成立的循环,通常用break语句来终止循环,死循环的else子句永远不会执行。
while True:
n=int(input("请输入:"))
if n==0:
break
print(n)
练习:
(1)任意输入一些整数,每次输入一个,当输入负数时,结束输入,当输入完后,打印您输入的这些数的和。
(2)写程序用while实现打印三角形,要求输入一个整数标书三角形的宽度和高度,打印出如下的三种直角三角形
*
**
***
****
****
***
**
*
****
***
**
*
(3)写程序求多项式的和:
1/1-1/3 1/5-1/7 1/9... 1/(2*n-1)的和,n最大取:1000000
打印这个和,打印这个和乘以4的值。
for语句
作用:
用来遍历可迭代对象的数据元素
可迭代对象是指依次获取数据元素的对象
可迭代对象包括:
字符串str
---以下后续再讲---
列表list
元祖tuple
字典dict
集合set
...
for语句语法:
for变量列表 in 可迭代对象:
语句块1
else:
语句块2
for语法说明:
(1)可迭代对象每次提供一个元素依次赋值给变量列表中的变量,赋值完毕后执行语句块1,重复执行此步骤,知道可迭代
对象不能提供数据为止。
(2)可迭代对象提供完所有元素后,执行else子句部分的语句块2,然后退出此for语句
(3)else子句可以省略(同while语句类似)
(4)当在循环内部用break终止循环时,else子句不会被执行。
示例:
s='ABCDE'
for ch in s:
print('ch-->',ch)
else:
print('for语句执行else子句')
print('程序退出')
练习:
任意输入一个字符串,判断这个字符串有几个空格' '(要求:不允许用s.count方法)
用for语句实现。
s=input('请输入一个字符串:')
count=0
for ch in s :
if ch == ' ' :
count =1
print('空格的个数是:',count)
range函数
格式:
>>>help(range)
函数:
range(stop)从0开始,每次生成一个整数后加1操作,直到stop为止(不包含stop)
range(start,stop[,step]),直到stop为止(不包含stop,且step可以是负整数)
作用:
用来创建一个生成一系列整数的可迭代对象(也叫整数序列生成器)
说明:
range返回的对象是可迭代对象.可以用于for语句中
示例:
range(4) #生成0,1,2,3
range(3,6) #生成3,4,5
range(1,10,2) #生成1,3,5,7,9
range(5,0,-2) #生成5,3,1
range(4,0) #空
for x in range(4):
print(x) # 0,1,2,3
for x in range(3,6):
print(x) # 3,4,5
练习:
用for语句打印1-20的整数,打印在一行
for x in range(1,21):
print (x,end=' ')
else:
print() #换行
求100内有哪些整数与自身 1的乘积,再对11求余结果等于8?
for x in range(100):
if x * (x 1) % 11 == 8:
print(x)
计算1 3 5 ... 99的和,用while和for两种语法实现
s = 0
i = 1
while i < 100:
s =i
i =2
print("和为:",s)
s=0
for i in range(1,100,2):
s =i
print("和为:",s)
for语句嵌套
for语句内部可以放任意语句,包含for语句和while语句
示例:
for x in 'ABC':
for y in '123':
print(x y)
示例:
count = 0
for x in range(5):
for y in range(10):
count =1
print(count) # 50
练习:
(1)写程序,输入一个整数n,代表正方形的宽度和高度
打印数字组成的正方形:
如:输入5
打印
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
s = int(input("请输入正方形的宽度和高度:"))
for x in range(s): #方法1
for y in range(s):
print((y 1),end=' ')
print()
for x in range(s): #方法2
for y in range(1,s 1):
print(y,end=' ')
print()
(2)写程序,输入一个整数n,代表正方形的宽度和高度
打印数字组成的正方形:
如:输入5
打印
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
for x in range(1,s 1): #方法1
for y in range(x,s x):
print("%2d" % y,end=' ') #超过9显示就有问题了
print()
for x in range(s): #方法2
y=x
while y<(s x):
print((y 1),end=' ')
y =1
print()
continue语句
作用:
用于循环语句(while,for语句)中,不再执行本次循环内continue之后的语句,
重新开始一次新的循环。
说明:
(1)在while语句中,执行continue语句将会直接跳转到while语句的真值表达式重新
判断循环条件。
(2)在for语句中,执行continue语句,将会从可迭代对象中取下一个元素,绑定变量
后再次进行循环。
示例:
for x in range(5)
if x ==2 :
continue
print(x) # 0 1 3 4
练习:
(1)输入一个整数用begin绑定,在输入一个整数用end绑定,打印出从begin~end(包含end)
的所有偶数(建议用continue语句跳过奇数)
begin = int(input("请输入一个开始整数:"))
end = int(input("请输入一个结束整数:"))
for x in range(begin,end):
if x % 2 == 1:
continue
print(x)
(2)用while循环,实现打印10以内的偶数
i=0
while i < 10 :
print(i)
i =2
i=0
while i < 10
if i % 2 ==1 :
i =1
continue
print(i)
i =1
(3)求1-100(包含100)之间所有不能被5,7,11整除的数的和是多少?
建议用continue语句实现)
#方法1
s = 0
i = 1
while i <=100:
if i % 5 == 0 or i % 7 == 0 or i % 11 == 0:
i =1
continue
s =i
i =1
print("和是:",s)
#方法2
s = 0
for x in range(1,101):
if x % 5 == 0 or x % 7 == 0 or x % 11 == 0:
continue
s =x
print("和是:",s)
循环总结:
while语句
for语句
-字符串
-range()函数
break语句
continue语句
练习:
输入一个整数,判断这个整数是否是素数(prime,素数是指只能被1和自身整除的数)
如:2 3 5 7 11...
方法:
用排除法,一旦n能被2~n-1的数整除就不是素数,否则就一定是素数。
# 方法1
s = int(input("请输入一个数:"))
if s < 2:
print(s,'不是素数')
exit()
flag=True
for x in range(2,s):
if s % x == 0 :
# print(s,"不是素数")
flag=False
break
if flag == True:
print(s,"是素数")
else:
print(s,"不是素数")
# 方法2
n = int(input("请输入一个数:"))
if n < 2:
print(n,'不是素数')
exit()
for x in range(2,n):
if n % x == 0 :
print(n,"不是素数")
break
else:
print(n,"是素数")
列表list
列表是由一系列特定元素组成的,元素和元系之间没有任何关联关系,但他们之间有先后顺序关系
列表是一种容器
列表是序列的一种
列表是可以被改变的序列
python中的序列类型简介(sequence)
字符串 str
列表 list
元祖 tuple
字节串 bytes
字节数组 bytearray
创建空列表的字面值
L = [] # L绑定空列表
创建非空列表:
L = [1,2,3,4]
L = ["北京","上海","重庆"]
L = [1,'two',3,'四']
L = [1,2,[3.1,3.2,3.3],4]
列表的构造(创建)函数list
list() 生成一个空的列表,等同于[]
list(iterable)用可迭代对象创建一个列表
示例:
L = list() L为空列表
L = list("ABCD") # L-> ['A','B','C','D']
L = list(range(1,10,2)) #L-> [1,3,5,7,9]
列表的运算
算数运算
= * *=
用于拼接列表
x = [x,y,3]
y = [4,5,6]
z = x y #[1,2,3,4,5,6]
= 用于原列表与左侧可迭代对象进行拼接,生成新的列表
x = [1,2,3]
x = "ABC" # =右侧必须是可迭代对象
x = [1,2,3,'A','B','C']
x = range(1,10,3)
* 生成重复的列表
x = [1,2,3] * 2
x = [1,2,3,1,2,3]
*= 用于生成重复的列表,同时用变量绑定新列表
x = [1,2]
x *= 3
x = [1,2,1,2,1,2]
列表的比较运算
运算符:
< <= > >= == !=
示例:
x = [1,2,3]
y = [2,3,4]
x != y #True
x > [1,2] #True
x < y #True
[1,3,2] > [1,2,3] #True
['AB','CD'] > ['AC','BC'] #False
['AB','CD'] < ['AC','BC'] #True
[1,'two'] > ['two',1] #TypeError
练习:
1、输入一个整数,代表树干的高度,打印一颗“圣诞树”,如:输入2
打印
*
***
*
*
输入3,打印
*
***
*****
*
*
*
2、用循环语句生成如下字符串:
'ABC.....XYZ'
'AaBbCc.....XxYxZz'
提示:用ord和chr函数结合循环语句实现(man assii找规律)
3、算出100-999以内的水仙花数(Narcissistic number),水仙花数是指
百位的3次方加上十位的3次方加上个位的3次方等于原数的数字
例如:
153 等于 1**3 5**3 3**3
参考答案:
153,370,...
解决办法:
#方法1
for x in range(100,1000)
bai = x // 100
shi = x % 100 // 10
ge = x % 10
if x == bai ** 3 shi ** 3 ge ** 3:
print(x)
#方法2
for x in range(100,1000)
s = str(x)
bai = int(s[0])
shi = int(s[1])
ge = int(s[2])
if x == bai ** 3 shi ** 3 ge ** 3:
print(x)
#方法3
for bai in range(1,10)
for shi in range(10)
for ge in range(10)
x = bai * 100 shi * 10 ge
if x == bai ** 3 shi ** 3 ge ** 3:
print(x)
列表的in与not in
1、判断一个数据元素是否存在于容器(列表)内,如果存在返回True,否则返回False
2、not in 的返回值与in运算符相反
示例:
x = [1,'Two',3.14,'四']
1 in x #True
3 not in x #True
'四' not in x #False
列表的索引(index)、切片(slice)
列表的索引语句:
列表[整数表达式]
用法:
列表的索引取值与字符串的索引取值规则完全相同
列表的索引分为正向索引和反向索引
示例:
L = ['A',2,'B',3]
print(L[1]) #2
x = L[2] #x='B'
列表的索引赋值
列表是可变的序列,可以通过索引赋值改变列表中的元素
语法:
列表[索引] = 表达式
示例:
x = [1,2,3,4]
x[2] = 3.14 #改变了第三个元素的值
列表的切片
列表[:]
列表的[::]
列表的切片取值返回一个列表,规则等同于字符串的切片规则
示例:
x = list(range(9))
y = x[1:9:2] # y = [1,3,5,7]
列表的切片赋值语法:
列表[切片] = 可迭代对象
说明:
切片赋值的赋值运算符的右侧必须是一个可迭代对象
示例:
L = [2,3,4]
L[0:1] = [1.1,2.2]
print(L) # [1.1,2.2,3,4]
L = [2,3,4]
L[:] = [7,8] # [7,8]
L = [2,3,4]
L[1:2] = [3.1,3.2,3.3] # [2,3.1,3.2,3.3,4]
L = [2,3,4]
L[1:1] = [2.1,2.2] # [2,2.1,2.2,4]
L = [2,3,4]
L[0:0] = [0,1] # [0,1,2,3,4]
L = [2,3,4]
L[3:3] = [5,6] # [2,3,4,5,6]
L = [2,3,4]
L[1:2] = [] # [2,4]
切片步长不为1的切片赋值:
L = list(range(1,9))
L[1::2] = [2.2,4.4,6.6,8.8]
print(L) # [1,2.2,3,4.4,5,6.6,7,8.8]
切片的注意事项:
对于步长不等于1的切片赋值,赋值运算符的右侧的可迭代对象提供元素的个数一定要等于
切片切出的段数:
如:
L = [1,2,3,4,5,6]
L[::2] = 'ABCD' #错误的
L[::2] = 'ABC' #正确的
del语句删除列表元素 (python使用引擎技术管理内存)
语法:
del 列表[索引]
del 列表[切片]
示例:
L = [1,2,3,4,5,6]
del L[0] # L = [2,3,4,5,6]
del L[-1] # L = [2,3,4,5]
L = [1,2,3,4,5,6]
del L [::2] # L = [2,4,6]
python3中常用的序列函数:
len(x) 返回序列的长度
max(x) 返回序列的最大值元素
min(x) 返回序列的最小值元素
sum(x) 返回序列中所有元素的和(元素必须是数值类型)
any(x) 真值测试,如果列表中其中一个值为真值则返回True,否则返回False
all(x) 真值测试,如果列表中其中所有值为真值则返回True,只要有一个为假,则返回False
练习:
1、已知有列表L=[3,5],用索引和切片操作,将列表改为L=[1,2,3,4,5,6]
将列表反转(前后对调),然后删除最后一个元素
print(L) #[6,5,4,3,2]
我做的如下:
L = [3,5]
L[0:0] = [1,2]
L[3::1] = [4,5,6]
print(L)
L = L[5::-1]
print(L)
del L[5]
print(L)
执行结果如下:
[1, 2, 3, 4, 5, 6]
[6, 5, 4, 3, 2, 1]
[6, 5, 4, 3, 2]
老师做法
L[1:1]=[4]
L[0:0]=[1,2]
L[len(L):len(L)]=[6]
L[:]=L[::-1]
del L[-1]
2、写程序,让用户循环输入一些整数,当输入-1时结束输入,将这些整数存于列表L中:
(1)打印您共输入了几个有效的数?
(2)打印您输入的数的最大数是多少?
(3)打印您输入的数的最小数是多少?
(4)打印您输入这些数的平均值。
我做的结果如下:
print("提示:输入-1可以退出输入!")
m = 0
L = list()
while True:
i = int(input("请输入一个数:"))
if i == -1:
break
L[m:m] = [i]
m =1
print("您输入的有效数为:",L)
print("您输入的最大数为:",max(L))
print("您输入的最小数为:",min(L))
print("您输入的这些数的平均值为:",sum(L)/len(L))
结果如下:
提示:输入-1可以退出输入!
请输入一个数:3
请输入一个数:4
请输入一个数:5
请输入一个数:-1
您输入的有效数为: [3, 4, 5]
您输入的最大数为: 5
您输入的最小数为: 3
您输入的这些数的平均值为: 4.0
老师做法
L = []
while True:
n = int(input("请输入(-1结束):"))
if n == -1:
break
L =[n]
列表方法:
python3中常用的列表方法:
help(list)就可查看到
L.sort(reverse=False) 倒序排序
L.pop(2) del L[2]
L.append(x)
练习:
写一个程序,输入多行文字,输入空格结束输入,将原输入的字符串存在列表L中,
(1)按原来输入的行的顺序反向打印这些行列:
输入:hello world
输入:welcome to china
输入:I like python
输入:<回车>
(2)打印您共输入了多少字符?
print("提示:输入回车则退出输出")
L = []
while True:
s = input("请输入字符串:")
if not s :
break
L.append(s)
print(L)
#方法1
s = 0
i = len(L) - 1
while i >=0 :
print(L[i])
s = len(L[i])
i -= 1
print("字符个数是:",s)
#方法2
m = 0
L.reverse()
for line in L:
print(line)
m = len(line)
print("字符个数是:",m)
字符串文本解析方法
split和join
S.split(sep=None)
将字符串,使用sep作为分隔符分隔S字符串,返回分隔后的字符串的列表,当不给定
参数时,用空白字符作为分隔符进行分隔
S.join(iterable)用可迭代对象中的字符串,返回一个中间用S进行分隔的字符串
例:
s = 'Beijing is capital'
L = s.split(' ') # L = ['Beijing','is','capital']
s = '\\'
L = ['C:','Programe files','python3']
s2 = s.join(L) # s2 = 'C:\Programe files\python3'
深拷贝 deep copy
通常只对可变对象进行复制,不可变对象通常不变。
import copy #导入copy模块
L = [3.1,3.2]
L1 = [1,2,L]
L2 = copy.deepcopy(L1) #深拷贝
print(L1) #[1,2,[3.1,3.2]]
print(L2) #[1,2,[3.1,3.2]]
L2[2][0] = 3.14
print(L1) #[1,2,[3.1,3.2]]
print(L2) #[1,2,[3.14,3.2]]
浅拷贝 shallow copy
是指在复制过程中只复制一层变量,不会复制深层变量绑定的对象的复制过程。
L = [3.1,3.2]
L1 = [1,2,L]
L2 = L1.copy() #等同于 L1[:] 浅拷贝
print(L1) #[1,2,[3.1,3.2]]
print(L2) #[1,2,[3.1,3.2]]
L2[2][0] = 3.14
print(L1) #[1,2,[3.14,3.2]]
print(L2) #[1,2,[3.14,3.2]]
列表推导式 list comprehension
列表推导式是用可迭代对象依次生成带有多个元素的列表的表达式
作用:
用简易方法生成列表
语法:
[表达式 for 变量 in 可迭代对象]
或
[表达式 for 变量 in 可迭代对象 if 真值表达式]
示例:
#以下生成一个数值为1-9的平方的列表
L = [x*x for x in range(1,10)]
练习:
用列表推导式生成1-100内奇数的列表结果[1,3,5,7,....99]
L = [2*x-1 for x in range(1,51)]
print(L)
L = [x for x in range(1,100,2)]
print(L)
L = [x for x in range(1,100) if x % 2 == 1]
print(L)
列表推导式的嵌套:
语法:
[表达式1 for 变量1 in 可迭代对象1 if 真值表达式1
表达式2 for 变量2 in 可迭代对象2 if 真值表达式2 ...]
示例:
L1 = [2,3,5]
L2 = [7,11,13]
#将L1中的全部元素与L2中的全部元素依次相乘后放到列表L3中
L3 = [x * y for x in L1 for y in L2]
print(L3)
day07-----------------------------------------------------------------------
元组 tuple
元组是不可变的序列,同list一样,元组可以存放任何任意类型的元素,一但元组生成,则它不可以
改变
元组的表示方式:
用小括号()括起来,单个元素括起来用逗号(,)
区分是单个对象还是元组
创建空元组的字符值:
t = ()
创建非空元组的字面值:
t = 200,
t = (20,)
t = (1,2,3)
t = 100,200,300
元组的错误示例:
t = (20) # t绑定整数
x,y,z = 100,200,300 # 序列赋值
x,y,z = 'ABC'
x,y,z = [10,20,30]
元组的构造函数 tuple
tuple() 生成一个空的元组,等同于()
tuple(iterable)用可迭代对象生成一个元组
示例:
t = tuple()
t = tuple(range(10))
t = tuple('ABC')
t = tuple((5,6,7,8))
t = tuple([5,6,7,8])
元组基本操作、方法
元组的算数运算符:
= * *=
用法与列表的用法完全相同
元组的比较运算:
< <= > >= == !=
规则与列表完全相同
in / not in
索引取值
切片取值
规则与列表完全相同
区别:
元组是不可变的对象,不支持索引赋值和切片赋值
元组方法:
见 help(tuple)
T.index(v[,begin[,end])
用于获取元组中V所在的索引位置
T.count(v) 用于获取元组中V的个数
(以上的方法同list中的index,count方法)
可以用于序列的函数:
len,max,min,sum,all,any
都可以用于元组中
三个构造函数:
str(obj)
list(iterable)
tuple(iterable)
用于创建相应的对象
其他函数:
reversed(seq) 返回反向顺序的可迭代对象
sorted(iterable,reverse=False)
返回已排序的表
示例:
fox x in reversed("ABCD"):
print(x) # D C B A
L = [8,6,3,5,7]
L2 = sorted(L)
print(L2) # [3,5,6,7,8]
L3 = sorted(L,reverse=True)
print(L3) # [8,7,6,5,3]
print(L) # 保持不变
#按字符顺序排序,不区分大小写
def f(ch):
code = ord(ch) #得到编码
if (97 26) > code >= 97:
code -= 32
return code
sorted('ACDacbdE',key=f)
#['A','a','b','C','c','D','d','E']
字典dict(dictionary)
1、字典是一种可变的容器,可以存储任意类型的数据。
2、字典中的每个数据都是用‘键’(key)进行索引,而不像序列可以用下标来进行索引。
3、字典的数据没有先后顺序关系,字典的存储是无序的。
4、字典中的数据以键(key)-值(value)对进行映射存储。
5、字典的键不能重复,且只能用不可变类型作为字典的键。
字典的字面值表示方式:
用{}括号起来,以冒号(:)分隔键-值对,各键值对用分号分隔开。
创建空字典
d = {}
创建非空的字典:
d = {'name':'tarena','age':15}
d = {'姓名':'小张'}
d = {1:'一',2:'二'}
字典的构造函数 dict
dict() 创建一个空字典,等同于{}
dict(iterable)用可迭代对象初始化一个字典
dict(**kwargs)关键字传参形式生成一个字典
示例:
d = dict()
d = dict([('name','tarena'),('age',15)])
d = dict(name='tarena',age=15)
不可变类型:
int,float,complex,bool,str,tuple,frozenset(固定集合),bytes(字节串)(后面会讲)
可变类型:
list,dict,set(集合),bytearray(字节数组)
字典基本操作
用[]运算符可以获取字典内'键'所对应的'值'
语法:
字典[键]
获取数据元素:
d = dict(name='tarena',age=15)
print(d['age']) # 15
添加/修改字典元素
字典[键] = 表达式
示例:
d = {}
d['name']='tarena' # 创建一个新的键值对
d['age'] = 15 # 创建键值对
d['age'] = 16 # 修改键值对
del语句删除字典的元素
语法:
del 字典[键]
示例:
d = {'name':'china','pos':'asia'}
del d['pos']
print(d)
del d['name']
print(d) # {}
字典的in / not in运算符
可以用in运算符来判断一个'键'是否存在于字典中,如果存在则返回True,否则返回False。
not in与in返回值相反
示例:
d = {'a':1,'b':2}
'a' in d # True
1 in d # False
100 not in d # True
2 not in d # True
字典的迭代访问:
字典是可迭代对象,字典只能对键进行迭代访问
d = {'name':'tarena',(2002,1,1):'生日'}
for x in d:
print(x)
# (2002,1,1)
name
for k in d:
print("键是:",k,"值是:",d[k])
字典常用方法
可以用于字典的内建函数
len(x) 返回字典键-值对的个数
max(x) 返回字典的键的最大值
min(x) 返回字典的键的最小值
sum(x) 返回字典所有键的和
any(x) 真值测试,只对键测试,如果其中一个键为True,结果为True
all(x) 真值测试,全部键为True时,结果才为True
一些方法:
D.clear()
D.pop(key)
D.copy() 浅拷贝
D.get(key,"没有此键")
D.keys()
D.value()
D.items()
for k,v in d.items():
print(k,v)
练习:
(1)写程序,实现以下需求:
将如下数据形成一个字典seasons
'键' '值'
1 '春季有1,2,3月'
2 '夏季有4,5,6月'
3 '秋季有7,8,9月'
4 '冬季有10,11,12月'
让用户输入一个整数代表这个季度,打印这个季度的信息,如果用户输入的信息
不在字典的键内,则打印信息不存在。
#我做的题意理解错误,应该是输入的内容打印出来
season = {}
while True:
i = int(input("请输入一个整数:"))
if i in [1,2,3]:
season[1] = '春季有1,2,3月'
elif i in [4,5,6]:
season[2] = '夏季有4,5,6月'
elif i in [7,8,9]:
season[3] = '秋季有7,8,9月'
elif i in [10,11,12]:
season[4] = '冬季有10,11,12月'
else:
print("您输入的信息不在字典的键内!")
break
print("你输入的字典内容为:",season)
#以下是老师输入的
#方法2
seasons = {1: '春季有1,2,3月',
2: '夏季有4,5,6月',
3: '秋季有7,8,9月',
4: '冬季有10,11,12月'}
n = int(input("请输入季度(1~4):"))
if n in seasons:
print(seasons[n])
else:
print("输入有误")
#方法3
print(seasons.get(n,"输入有误!"))
(2)写程序,输入一段字符串,打印出这个字符串中出现过的字符及出现过的次数:
如:
输入:ABCDABCABA
输出:
A:4次
B:2次
C:3次
D:1次
注:不要求打印的顺序。
此题我不会做,老师做法如下
#方法1
s = input("请输入一段字符串:")
print(s)
d = {}
for ch in s:
if ch not in d:
d[ch] = 1
else:
d[ch] = 1
for k in d:
print(k,":",d[k],"次")
#方法2
print("方法2-----------------")
for ch in s:
if ch not in d:
d[ch]=None
for k in d:
print(k,":",s.count(k),"次")
字典推导式
字典推导式是用可迭代对象依次生成字典内元素的表达式
语法:
{键表达式:值表达式 for 变量 in 可迭代对象 [if 真值表达式]}
注:[]的内容代表可省略
示例:
>>> d = {x:x ** 2 for x in range(10)}
>>> d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>> d = {x:x ** 2 for x in range(10) if x % 3 ==0}
>>> d
{0: 0, 3: 9, 6: 36, 9: 81}
练习:
(1)有字符串列表如下:
L = ['tarena','xiaozhang','xiaowang']
生成如下字典:
d = {'tarena':6,'xiaozhang':9,'xiaowang':8}
注:字典值是键的长度
解答如下:
L = ['tarena','xiaozhang','xiaowang']
d = {k:len(k) for k in L}
print(d)
(2)编号列表如下:
Nos = [1001,1002,1003,1004]
names = ['Tom','Jerry','Spike','Tyke']
生成用Nos数据为键,以names为值的字典,如下:
{1001:'Tom',1002:'Jerry',......}
解答如下:
Nos = [1001,1002,1003,1004]
names = ['Tom','Jerry','Spike','Tyke']
#方法1
d = {Nos[i]:names[i] for i in range(min(len(Nos),(len(names))))}
print(d)
#方法2
d = {x:names[Nos.index(x)] for x in Nos}
print (d)
练习:
(1)用字符串s = "ABC" 和 s2 = "123" 生成如下列表
['A1','A2','A3','B1','B2','B3','C1','C2','C3']
解决方法:
s = 'ABC'
s2 = '123'
L = [x y for x in s for y in s2]
print(L)
(2)有一些数存在于列表L中,如:L = [1,3,2,1,6,4,2,......98,82](此数据自己定义)
将列表L中的数存入于另一个列表L2中(要求重复出现多次的数字只在L2列表中保留一份)
解决办法:
L = [1,3,2,1,6,4,2,98,82]
#方法1
L2 = []
for x in L:
#如果x不在L2中,将其放入L2中
if x not in L2:
L2.append(x)
print(L2)
#方法2
L2 = L.copy()
for y in L2:
if L2.count(y) > 1:
L2.remove(y)
print(L2)
#方法3
L2 = L.copy()
i = 0
while i < len(L2):
if L2.count(L2[i]) > 1:
del L2[i]
continue # i原地不动
i = 1
print(L2)
(3)生成前40个斐波那契数(Fibonacci) 1 1 2 3 5 8 13 ...
(自第三个起之后的所有数为前连个数之和),要求将这些数保存在列表中,最后打印列表中的这些数
提示:用循环、列表和变量组合可以实现
解决办法:
#方法1
a = 0
b = 1
L = []
while len(L) < 40:
a,b = b,a b #序列赋值
L.append(a)
print(L)
#方法2
L = [1,1]
while len(L) < 40:
L.append(L[-1] L[-2])
print(L)
(4)写一个程序,输入一些单词和解释,将单词作为键,将解释作为值,将这些数据存入字典中,
然后输入查询的单词,显示出此单词的解释。
#方法1--周微
d = {}
while True:
s1= input("请输入一个单词:")
if s1 == '':
break
s2 = input("请输入这个单词的意思:")
if s2 == '':
break
d[s1] = s2
print(d)
while True:
s = input("请输入要查询的单词:")
if s == '':
break
if s not in d:
print("您输入的单词未在字典中找到,请重新输入:")
else:
print(s,"的意思是:",d[s])
(5)学生管理项目准备工作:
写一个程序,任意输入n个学生的信息,形成字典后存于列表中:
学生的信息包括:
姓名(字符串)
年龄(整数)
成绩(整数)
循环输入学生信息,直到输入学生姓名为空时结束输入,最后形成字典列表如下:
L = [
{'name':'xiaozhang','age':20,
'score':100},
{'name':'xiaoli','age':21,
'score':98},
{'name':'xiaowang','age':19,
'score':89},
...
]
将以上列表显示如下的表格:
------------- ------ ------
| name | age | score|
| xiaozhang | 20 | 100 |
| xiaoli | 21 | 98 |
| xiaowang | 19 | 89 |
------------- ------ ------
#方法1-周微
L = []
t = ()
s = ''
while True:
name = input("请输入学生的姓名:")
if name == '':
break
age = int(input("请输入学生的年龄:"))
score = int(input("请输入学生的分数:"))
d = {'name':name,'age':age,'score':score}
L = [d]
t = (name,)
print(d)
print(L)
print(t)
m = len(max(t))
print(' ' '-' * (m 2) ' ' '-' * (5) ' ' '-' * (8) ' ')
print('|' 'name'.center(m 2) '|' 'age'.center(5) '|' 'score'.center(8) '|')
for x in L:
for y in x:
s = str(x[y])
if y == 'name':
print('|',s.center(m 1),end = '')
if y == 'age':
print('|',s.center(4),end = '')
if y == 'score':
print('|',s.center(6),'|')
print(' ' '-' * (m 2) ' ' '-' * (5) ' ' '-' * (8) ' ')
day08-----------------------------------------------------------------------
回顾
集合 set
集合是可变的容器
集合内的数据对象是唯一的(不能重复多次的)
集合是无序的存储结构,集合中的数据没有先后关系
集合内的元素必须是不可变对象
集合是可迭代的
集合是相当于只有键没有值的字典(键则是集合的数据)
创建空的集合
s = set() # set()创建一个空的集合
创建非空的集合
s = {1,2,3} # 集合的三个整数1,2,3
集合的构造函数 set
set() 创建空集合
set(iterable)用可迭代对象创建一个新的集合对象
示例:
s = set("ABC")
s = set('ABCCBA')
s = set({1:"一",2:'二',5:'五'})
s = set([1,3.14,False])
s = set((2,3,5,7))
s = set([1,2,[3.1,3.2],4]) #错的[3.1,3.2]是可变对象
集合运算、常用方法
交集,并集,补集,子集,超集
& 生成两个集合的交集
s1 = {1,2,3}
s2 = {2,3,4}
s3 = s1 & s2
# s3 = {2,3}
| 生成两个集合的并集
s1 = {1,2,3}
s2 = {2,3,4}
s3 = s1 | s2
# s3 = {1,2,3,4}
- 生成两个集合的补集
s1 = {1,2,3}
s2 = {2,3,4}
s3 = s1 - s2 #属于s1不属于s2
# s3 = {1}
^ 生成两个集合的对称补集
s1 = {1,2,3}
s2 = {2,3,4}
s3 = s1 ^ s2 #等同于s3 = (s1 - s2) | (s2 - s1)
# s3 = {1,4}
< 判断一个集合是另一个集合的子集
> 判断一个集合是另一个集合的超集
s1 = {1,2,3}
s2 = {2,3}
s2 < s1 # True 判断子集
s1 > s2 # True 判断超集
== != 集合相同/不同
s1 = {1,2,3}
s2 = {2,3,1}
s1 == s2 #True
s1 != s2 #False 集合的数据没有先后关系
in / not in 运算符
等同于字典,in运算符用于集合中,当某个值存在于集合中,则为真,否则为假
not in 与 in 返回值相反
示例:
s = {1,'Two',3.14}
1 in s #True
2 in s #False
3.14 not in s #False
4 not in s #True
python3中可用于集合的函数:
len(x)
max(x)
min(x)
sum(x)
any(x)
all(x)
集合是可迭代对象,即可用于for语句中,打印的顺序不保证每次都一样
s = {1,2,3}
for x in s:
print(x)
练习:
经理:曹操,刘备,周瑜
技术员有:曹操,周瑜,张飞,赵云
用集合求:
(1)既是经理也是技术员的有谁?
(2)是经理,但不是技术员的有谁?
(3)是技术员,不是经理的都有谁?
(4)张飞是经理吗?
(5)身兼一职的人有谁?
(6)经理和技术员共有几个人?
解决办法:
s1 = {'曹操','刘备','周瑜'}
s2 = {'曹操','周瑜','张飞','赵云'}
print('经理有:',s1)
print('技术员有:',s2)
print("既是经理也是技术员的有谁?",s1 & s2)
print("是经理,但不是技术员的有谁?",s1 - s2)
print("是技术员,不是经理的都有谁?",s2 - s1)
if '张飞' in s1:
print("张飞是经理")
else:
print("张飞是技术员")
print("身兼一职的人有谁?",s1 ^ s2)
print("经理和技术员共有几个人?",len(s1 | s2))
print("经理和技术员共有%d个人?"%len(s1 | s2))
集合的方法:
思考:集合是可变对象,有方法能添加、删除集合的数据吗?
s.add(e) 添加集合数据
s.remove(e) 删除,报错有提示
s.discard(e) 删除,没有报错
s.clear(s2) 清空集合
s.copy(s2) 浅拷贝
s.pop(s2) 删除随机元素
s.update(s2)
s1 = s1 | s2 不等于 s1 |= s2
对于不可变对象,有时候复合赋值运算符不同于运算后再赋值
练习:
任意输入一系列单词,存入集合中,当输入空字符串时结束输入。
(1)打印您输入的单词的种类数(去重)
(2)每个单词都打印到终端上显示
思考:如何让打印的次序和输入的次序一致?
L = []
while True:
s = input("请输入一系列单词:")
if not s:
break
L.append(s)
s = set(L) # 集合可以去重
print("您共输入%d种单词"%len(s))
for words in s:
print(words)
如何保证输入顺序?
# 方法1,不用集合
L2 = []
for x in L:
if x not in L2:
L2.append(x)
for x in L2:
print(x)
# 方法2,用集合
s = set(L) # 去重
for x in L :
if x in s :
print(x)
s.discard(x) # 删除已经打印过的
集合推导式
用可迭代对象来创建(生成)集合的表达式
语法:
{表达式 for 变量 in 可迭代对象 [if 真值表达式]}
[] 括号部分内容代表可省略
示例:
L = [2,3,5,7,3,5,7,11]
s = {x**2 for x in L} #集合自动去重,所以值的结果你就明白了
# s ={4,9,25,49,121}
集合推导式的嵌套规则与列表推导式嵌套相同
练习:
1、模拟一个点名系统,已知全班学生名单,随机打印学生的姓名进行点名,并得到此学生是否已到信息,输入'y'代表
已到,其他输入代表未到场,点击结束后打印未到者的名单。
names = ['tom','jerry','spike','tyke']
s = set(names) # 集合去重,里面存储是乱序的
L = []
for n in s:
info = n "已到?(y):"
r = input(info)
if r != 'y':
L.append(n) #把未到场的姓名加入到L列表中
print("未到人的名单如下:")
for n in L:
print(n,end=' ')
print()
可变对象容器:
列表、字典、集合
字节数组用于放字节
固定集合
问题:能用集合作为字典的键吗?
固定集合 frozenset
固定集合是不可变的,无序的,含有唯一元素的集合
作用:
固定集合可以作为字典的键,也可以作为集合的值(元素)
创建空的固定集合:
fs = fronzenset()
创建非空的固定集合
fs = fronzenset ([2,3,5,7])
构造函数:
fronzenset()
fronzenset(可迭代对象) # 同set函数一致,返回固定集合
固定集合的运算:
& 交集, | 并集,- 补集,^ 对称补集
> >= < <= == !=
in / not in
(以上运算规则等同于set中的用法)
固定集合的方法:
相当于集合的全部方法去掉修改集合的方法
fz.difference()
fz.copy()
...
阶段总结
数据类型
不可变数据类型
bool int float complex str tuple fronzenset bytes(以后再学)
可变数据类型
list dict set bytearray(以后再学)
值:
None True False...
运算符:
- * / // % **
> >= < <= == !=
is / is not
in / not in
not and or
& | ^
(正号) -(负号)
表达式
1
1 2
len([1,2,3])
条件表达式
x if x > y else y
全部的推导式:
列表,字典,集合推导式(三种)
语句:
表达式语句:
print("abc")
'hello'
赋值语句:(创建变量和改变变量,不能改变对象)
a = 100
a = b = c = 200
x,y = 100,200 (序列赋值)
if语句
while语句
for语句
continue语句
break语句
pass语句
del语句 (删除变量)
内建函数:
len(x)
max(x)
min(x)
sum(x)
any(x)
all(x)
---------------
bool(x)
int(x)
float(x)
complex(x)
str(x)
list(x)
tuple(x)
dict(x)
set(x)
fronzenset(x)
---------------
abs(x)
round(x)
pow(x,y,...)
---------------
bin(x)
oct(x)
hex(x)
chr(x)
ord(x)
---------------
range([start,]stop[,step])
---------------
input(x)
print(...)
函数 function
什么是函数?
函数是可以重复执行的语句块,可以重复使用。
作用:
1、用于封装语句块,提高代码的重用性。
2、定义用户级别的函数。
函数定义(创建)语句def语句的语法:
def 函数名(形参列表):
语句块
说明:
1、函数的名字就是语句块的名称
2、函数名的命名规则与变量名相同(函数名必须为标识符)
3、函数有自己的名字空间,在函数外部不可以访问函数内部的变量,在函数内部可以访问函数外部的变量,
通常让函数处理外部数据需要用参数传入一些数据
4、函数的参数列表可以为空
5、语句部分不能为空,如果为空需要填充pass语句
示例:
#创建函数
def say_hello():
print("hello world")
print("hello everyone!!!")
#调用函数
say_hello()
函数的调用
函数名(实际调用传递参数列表)
注:实际调用传递参数以后称为实参
说明:
函数调用是一个表达式
如果没有return语句,此函数执行完毕后返回None对象
如果函数需要返回其他的对象需要用到return语句
def mymax(a,b)
print('a =',a)
print('b =',b)
if a > b:
print(a,"大于",b)
else:
print(a,"小于等于",b)
mymax(20,30)
mymax("abc",'123')
练习:
1、素数prime函数练习
1)写一个函数isprime(),判断x是否为素数,如果是素数,返回True,否则返回False。
2)写一个函数prime_m2n(m,n),返回从m开始到n结束(不包含n)的范围内的素数列表
如:
L = prime_m2n(1,10)
print(L) # [2,3,5,7]
3)写一个函数primes(n),返回指定范围内素数(不包含n)的全部素数的列表,并打印这些素数。
如:
L = prime(20)
print(L) # [2,3,5,7,11,13,17,19]
1)打印100以内的全部素数
2)打印100以内全部素数的和
代码如下:
def isprime(x):
if x <= 1:
return False
for i in range(2,x):
if x % i == 0:
return False
return True
def prime_m2n(m,n):
L = []
for i in range(m,n)
if isprime(i):
L.append(i)
return L
'''
return [x for x in range(m,n) if isprime(x)]
'''
def primes(n):
return prime_m2n(0,n)
L = primes(20)
print(L)
for x in primes(100):
print(x)
print("100内全部素数的和是:",sum(primes(100)))
2、修改之前的学生信息管理程序:
编写两个函数用于封装,录入学生信息和打印学生信息的功能
1)def input_student():
此函数获取学生的信息,并返回学生信息的字典的列表
2)def ouput_student(L):
以表格形式再打印学生信息
验证测试:
L = input_student()
output_student(L)
print("再添加几个学生信息")
L = input_student()
print("添加学生后的学生信息如下:")
output_student(L)
代码如下:
#此函数获取学生信息,并返回学生信息的字典的列表
def input_student():
L = []
#d = {} 此处所有学生共用一个字典,会出错
while True:
name = input("请输入学生姓名:")
if not name:
break
age = int(input("请输入学生年龄:"))
score = int(input("请输入学生成绩:"))
d = {} #重新创建一个新的字典
d['name'] = name
d['age'] = age
d['score'] = score
L.append(d)
return L
def output_student():
#以表格形式再打印学生信息
print(' ------------ ------ -------- ')
print('| name | age | score |')
print(' ------------ ------ -------- ')
for d in L: #d绑定的是字典
t = (d['name'].center(12),str(d['age']).center(6),str(d['score']).center(7))
line = "|%s|%s|%s" % t # t是元祖
print(line)
print(' ------------ ------ -------- ')
L = input_student()
output_student(L)
print("再添加几个学生信息")
L = input_student()
print("添加学生后的学生信息如下:")
output_student(L)
-------------------------------待做------------------------------------------------
今天的练习
1、写一个函数mysum,要求给出一个数n,求 1 2 3 4 ..... n的和
如:
print(mysum(100)) # 5050
print(mysum(10)) # 55
2、写一个函数myfac(n)来计算n!(n的阶乘)
n!=1*2*3*4...*n
如:
print(myfac(5)) # 120
print(myfac(4)) # 24
3、写一个函数,求
1 2**3 3**3 ... n**n的和 (n给个小点的数)
4、修改之前的学生信息管理程序,实现添加菜单和选择菜单操作功能:
菜单:
---------------------------------------
| 1)添加学生信息 |
| 2)查看所有学生信息 |
| 3)修改学生的成绩 |
| 4)删除学生信息 |
| q)退出 |
---------------------------------------
请选择:1
请输入姓名:....
请选择:3
请输入修改学生的姓名:...
(要求:每个功能都对应一个函数)
day09-------------2019-10-09----------------------------------------------------------
return语句
语法:
return [表达式]
[] 代表可以省略
作用:
用于函数中,结束当前函数的执行,返回到调用该函数的地方,同时返回一个对象的引用关系。
说明:
1、return语句后跟的表达式可以省略,省略后相当于return None
2、如果函数没有return语句,则函数执行完最后一条语句后返回None(相当于在最后增加了一条return None)
3、函数调用一定会返回一个对象的引用
4、return后面的语句不会被执行
练习:
写一个函数mymax,实现返回两个数的最大值:
如:
def mymax(a,b):
..此处自己填写
print(mymax(100,200)) # 200
print(mymax(50,10)) # 50
print(mymax('ABC','ABCD')) # ABCD
完成如下:
#方法1
def mymax(a,b):
if a > b:
return a
else:
return b
print(mymax(100,200)) # 200
print(mymax(50,10)) # 50
print(mymax('ABC','ABCD')) # ABCD
#方法2
if a > b:
s = a
else:
s = b
return s
#方法3
if a > b:
return a
return b
写一个函数input_number
def input_number():
...
此函数用来获取用户循环输入的整数,当用户输入负数时结束输入
将用户输入数以列表的形式返回,再用再建函数max,min,sum显示出
用户输入的最大值、最小值及和
如:
L = input_number()
print(L) #打印此列表
print("用户输入的最大数是:",max(L))
print("用户输入的最小数是:",min(L))
print("用户输入的和是:",sum(L))
结果如下:
def input_number()
L = []
while True:
n = int(input("请输入一个数:"))
if n < 0:
return L
L.append(n)
L = input_number()
print(L) #打印此列表
print("用户输入的最大数是:",max(L))
print("用户输入的最小数是:",min(L))
print("用户输入的和是:",sum(L))
函数的参数传递
传递方式
位置传递
序列传参
关键字传参
字典关键字传参
位置传参:
实际参数(实参)的对应关系与形式参数(形参)
的对应关系是按位置来依次对应的
示例:
def myfun(a,b,c):
pass
myfun(1,2,3)
说明:
实际参数和形式参数通过位置进行传递的匹配
实参个数必须与形参个数相同
序列传参:
序列传参是指在函数调用过程中,用*将序列拆解后按位置传参的方式进行参数传递
示例:
def myfun(a,b,c)
pass
s = [1,2,3]
myfun(*s) # *表示把s拆开
s2 = "ABC"
myfun(*s2)
关键字传参:
关键字传参是指传参时,按着形参的名称给形参赋值,实参和形参按名称进行匹配
示例:
def myfun(a,b,c)
pass
myfun(b=22,c=33,a=11) #等同于myfun(11,22,33)
myfun(c=3,b=2,a=1)
说明:
实参和形参可以不按位置匹配
字典关键字传参:
是指实参为字典,将字典用**拆解后进行关键字传参
示例:
def myfun(a,b,c):
pass
d = {'c':33,'b':22,'a':11}
myfun(**d) #拆解字典后再传参
说明:
字典的键名和形参名必须一致
字典键名必须为字符串
字典键名要在形参中存在
函数的综合传参
参数传参方式,在能确定形参能唯一匹配到相应实参的情况下任意组合
示例:
def myfun(a,b,c):
pass
#正确的
myfun(100,*[200,300]
myfun(*'AB',300)
myfun(100,c=300,b=200)
myfun(1,**{'c':3,'b':2})
myfun(**{'c':3,'b':2},a=1)
#错误,不能确定1给谁
myfun(b=2,c=3,1)
声明:
先位置传参,后关键字传参
练习:
(1)写一个函数sum3(a,b,c):
用于返回三个数的和。
(2)写一个函数pow3(x),用于返回x的三次方(立方)
用以上函数计算
1**3 2**3 3**3的和
计算1 2 3的和的立方,即(1 2 3)**3
def sum3(a,b,c):
return a b c
def pow3(x):
return x ** 3
print(sum3(pow3(1),pow3(2),pow3(3))
print(pow3(sum3(1,2,3)))
以下讲的是函数的形参(如何接收实参)
函数的缺省参数(默认参数)
语法:
def 函数名(形参名1=默认实参1,形参名2=默认实参2,...):
示例:
def info(name,age=1,address="未填写"):
print(name,"今年",age,'岁,家庭地址是:',address)
info('tarena',15)
info('小魏',20,'北京市朝阳区')
info('小李')
说明:
1、缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则即
右侧的所有参数都必须有缺省参数。
如:
def test(a,b=10,c): # <-----是错的
pass语句
2、缺省参数可以有0个或多个,甚至全部都有缺省参数都可以。
练习:
1、写一个函数mysum(),可以传入两个实参或三个实参,如果传入两个
实参,则返回两个实参的和;如果传入三个实参,则返回前两个实参的
和对第三个实参求余的结果。
print(mysum(1,100)) # 101
print(mysum(2,10,7)) # 5 返回:(2 10)%5
实现如下:
def mysum(x,y,z):
if z == 0:
return x y
return (x y) % z
#方法2
def mysum(x,y,z=None):
if z is None:
return x y
return (x y) % z
函数的形参定义方式
位置形参
星号元组形参
命名关键字形参
双星号字典形参
位置形参:
语法:
def 函数名(形参1,形参2,...):
语句块
星号元组形参:
语法:
def 函数名(*元组形参名):
语句块
作用:
手机多余的位置参数
说明:
元组形参名通常用:'args'
示例:
def func(*args):
print("参数个数是:",len(args))
print('args=',args)
func(1,2,3,4)
func("hello","world",1,2,3)
练习:
写一个函数mysum,可以传入任意个实参的数字,返回所有实参的和
def sum(...):
print(mysum(1,2,3,4) # 10
print(mysum(2,4,6) # 12
实现结果如下:
def sum(*args):
return sum(args)
#方法2
def sum(*args):
s == 0
for x in args:
s =x
return s
命名关键字形参:
语法:
def 函数名(*,命名关键字形参):
语句块
或
def 函数名(*args,命名关键字形参):
语句块
作用:
所有的参数都必须用关键字传参或字典关键字传参传递
示例:
def fn(*,d,e):
print('d=',d)
print('e=',e)
fn(d=100,e=200) #合法调用
fn(1,2) #不合法,不能用位置传参
def fm(*args,d,e):
print(args)
print('d=',d)
print('e=',e)
fm(1,2,d=100,e=200)
fm(*"AB",##{'e':20,'d':10})
双星号字典形参
语法:
def 函数名(**字典形参名):
语句块
作用:
收集多余的关键字形参
说明:
通常字典形参名定为:"kwargs"
示例:
def func(**kwargs):
print("关键字参数个数是:",len(kwargs))
print("kwargs=",kwargs)
func(name='tarena',age=15)
func()
函数的参数说明:
缺省参数,位置形参,星号元组形参,命名关键字形参和双星号字典形参可以混合使用
函数参数自左至右的顺序为:
位置形参
星号元组形参
命名关键字形参
双星号字典形参
综合示例:
def f1(a,b,*args,c,**kwargs):
pass
f1(1,2,3,4,d=6,c=5,e=7)
f1(*"hello",d=6,**{'c':5,'e':7})
函数的不定长参数
def fn(*args,**kwargs):
pass
#可以接收任意的位置传参和关键字传参
练习:
写一个myrange函数,此函数返回一个符合range规则的整数列表
如:
L = myrange(3)
print(L) # [0,1,2]
L = myrange(3,6)
print(L) # [3,4,5]
L = myrange(1,10,3)
print(L) # [1,4,7]
实现结果如下:
def myrange(start,stop=None,step=1):
if stop is None: #如果传入一个参数
stop = start
start = 0
L =[]
i = start
while i < stop:
L.append(i)
i = step
return L
L = myrange(3)
print(L) # [0,1,2]
L = myrange(3,6)
print(L) # [3,4,5]
L = myrange(1,10,3)
print(L) # [1,4,7]
练习:
结果如下:
---1-----
def myfun(a,b):
print('最大值是:',max(a,b))
print('和是:',a b)
print('积是:',a * b)
i = a
while i < b:
if i % 2 == 0:
print(i)
i = 1
myfun(3,10)
---2-----
def get_lastday(y):
#根据今天的桃子数y,计算昨天的桃子树x
x = (y 1) * 2
return x
p = 1 #第十天的桃子数
day = 10 #用来表示当前是第几天
while day > 1:
day -= 1
p = get_lastday(p)
print("第",day,"天的桃子是:",p)
---3-----
i = 1 # 完全数的开始值
while True:
# 判断是否是完全数,如果是则打印
L = []
for x in range(1,i):
if i % x == 0: #如果x是i的因数
L.append(x) #放在列表中
#此时L列表是i所有的因数
if sum(L) == i:
print(i,"是完全数")
i = 1
#方法2,用函数来求完全数,增加程序的可读性
def main():
#此函数计算所有的完全数
i = 1 # 完全数的开始值
while True:
# 判断是否是完全数,如果是则打印
if is_perfect_number(i):
print(i,"是完全数")
i = 1
def is_perfect_number(i):
L = [] #每次循环开始都创建一个新列表,用来存因数
for x in range(1,i):
if i % x == 0: #如果x是i的因数
L.append(x) #放在列表中
#此时L列表是i所有的因数
if sum(L) == i:
return True
return False
main()
练习:
1、素数prime函数练习
(1)写一个函数isprime(x)判断x是否为素数,如果是素数,返回True,否则返回False。
(2)写一个函数prime_m2n(m,n),返回从m到n结束(不包含n)的范围内的素数列表
如:
L = prime_m2n(1,10)
print(L) # [2,3,5,7]
(3)写一个函数prime是(n),返回指定范围内素数(不包含n)的全部素数的列表,并打印这些素数。
如:
L = prime(20)
print(L) # [2,3,5,7,11,13,17,19]
打印100以内的全部素数
打印100以内的全部素数的和
2、修改之前的学生信息管理程序:
编写两个函数用于封装,录入学生信息和打印学生信息的功能
1)def input_student():
此函数获取学生的信息,并返回学生信息的字典的列表
2)def ouput_student(L):
以表格形式再打印学生信息
验证测试:
L = input_student()
output_student(L)
print("再添加几个学生信息")
L = input_student()
print("添加学生后的学生信息如下:")
output_student(L)
day10-------------2019-10-14----------------------------------------------------------
全局变量、局部变量
局部变量:
定义在函数内部的变量为局部变量(函数的形参也是局部变量)
局部变量只能在函数内部使用
局部变量在函数调用时才能够被创建,在函数调用之后会自动销毁
全局变量
定义在函数外部,模块内部的变量称为全局变量
全局变量,所有的函数都可以直接访问(但函数内部不能将其直接赋值)
局部变量说明:
(1)在函数内首次对变量赋值是创建局部变量,再次为变量赋值是修改局部变量的绑定关系
(2)在函数内部的赋值语句不会对全局变量造成影响
(3)局部变量只能在其被声明的函数内部访问,而全局变量可以在整个模块范围访问
globals和locals函数
global()返回当前全局作用域内变量的字典
locals()返回当前局部作用域内变量的字典
示例:
a = 1
b = 2
c = 3
def f1(c,d):
e = 300
print("locals()返回:",locals())
print("global()返回:",globals())
for k,v in globals().items():
print(k,'--->',v)
print(c) # 100
print(globals()['c']) # 得到了全局变量c的值,值是3
f1(100,200)
函数变量、函数作为参数
函数名是变量,它在创建函数时绑定一个函数
示例1:
def f1():
print("f1被调用")
fx = f1
fx() # 等同于f1()
示例2:
def f1():
print("hello")
def f2():
print("world")
f1,f2 = f2,f1 #交换两个变量的绑定关系
f1() # 请问打印结果是什么?world?
一个函数可以作为另一个函数的参数传递
示例3:
def f1():
print("hello")
def f2():
print("world")
def fx(fn):
print(fn)
fn() # 调用谁?
fx(f1) #此语句在做什么
fx(f2)
示例4:
def fx(a,fn):
return fn(a)
L = [5,9,4,6]
print('最大值是:',fx(L,max))
print('最小值是:',fx(L,min))
print('和是:',fx(L,sum))
函数作为返回值
函数可以返回另一个函数(即:另一个函数可以返回一个函数)
示例:
def get_fx():
s = input('请输入您要做的操作:')
if s == '求最大':
return max
elif s == '求最小':
return min
elif s == '求和':
return sum
L = [2,4,6,8,10]
print(L)
f1 = get_fx()
print(f1(L))
练习:
写一个计算器解释执行器:
已知有如下函数:
def myadd(x,y):
return x y
def mymul(x,y):
return x * y
def get_op(s):
代表操作字符串:‘加’‘乘’,此处自己实现
主函数:
def main():
while True:
s = input('请输入计算公式:')
如:10加20
L = s.split() #空格拆分
a,s,b = L
a,b = int(a),int(b)
fn = get_op(s)
print("结果是:",fn(a,b)) #结果是30
实现如下:
def myadd(x,y):
return x y
def mymul(x,y):
return x * y
def mysub(x,y):
return x - y
def get_op(s):
if s == '加' or s == ' '
return myadd
elif s == '乘' s == '*'
return mymul
elif s == '减' s == '-'
return mysub
def main():
while True:
s = input('请输入计算公式:')
L = s.split() #空格拆分
a,s,b = L
a,b = int(a),int(b)
fn = get_op(s)
print("结果是:",fn(a,b))
main()
函数的嵌套
函数的嵌套定义是指一个函数里用def语句来创建其他的函数
示例:
def fn_outer():
print("fn_outer被调用")
def fn_inner():
print("fn_inner被调用")
fn_inner()
fn_inner()
print("fn_outer调用结束")
return fn_inner
fn_outer()
fn_outer()
fn_inner() 此时会出错
fx = fn_outer()
fx() 调用fn_outer()内部创建的函数
python作用域
作用域也叫名字空间,是访问变量时,查找变量名的范围空间
python的四个作用域LEGB
局部作用域 local function L
外部嵌套函数作用域 enclosing function locals E
函数定义所在模块(文件)的作用域 global(mudule) G
python内置模块的作用域 builtin(python) B
示例:
v = 100 全局作用域
def fun1():
v = 200 外部嵌套函数作用域
print("fun1内的v=",v)
def fun2():
v = 300 局部作用域
print("fun2内的v=",v)
fun2()
fun1()
print("v=",v)
变量名的查找规则:
L--->E --->G--->B
在默认情况下,对变量名赋值会创建或改变作用域内的变量
global语句
问题:
v = 100
def f():
v = 200 希望此赋值语句操作的是全局变量
f()
print(v) 200怎么办
global语句:
作用:
1、告诉解释器,global语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,
也称作全局变量
2、全局声明(global)将赋值变量映射到模块内部的作用域
语法:
global 变量1,变量2,...
示例:
v = 100
def fn():
global v
v = 200
fn()
print(v) # 200
说明:
1、全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为是局部变量)
2、全局变量在函数内部不经过声明就可以直接访问
3、不能先声明局部的变量,再用global声明为全局变量,此做法不符合规则
def f3()
v = 100
global v
print(v) 以上会报语法错误
应该这样写
def f3()
global v
v = 100
print(v)
4、global变量列表里的变量不能出现在此作用域内的形参列表里
v = 100
def f2(v)
global v #此处必然会出错
v = 300
f2(v)
print(v)
nonlocal语句(非局部)
作用:
告诉解释器,nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量
语法:
nonlocal 变量名1,变量名2,...
示例:
var = 100
def f1():
var = 200
print("f1里面的var=",var)
def f2():
var = 300 #此处想要修改f1的var变量怎么办?
print("f2里的var=",var)
f2()
print("f2调用结束后的var值为",var)
f1()
print("全局的var=",var)
var = 100
def f1():
var = 200
print("f1里面的var=",var)
def f2():
global var
var = 300
print("f2里的var=",var)
f2()
print("f2调用结束后的var值为",var)
f1()
print("全局的var=",var)
var = 100
def f1():
var = 200
print("f1里面的var=",var)
def f2():
nonlocal var
var = 300 #此处想要修改f1的var变量怎么办?在上面加上nonlocal
print("f2里的var=",var)
f2()
print("f2调用结束后的var值为",var)
f1()
print("全局的var=",var)
说明:
1、nonlocal语句只能在被嵌套函数内部进行使用
2、nonlocal变量将对外部嵌套函数的作用域的变量进行操作
3、当有两层或者两层以上的函数嵌套时,访问nonlocal变量只对最近一层的变量进行操作
4、nonlocal语句的变量列表里的变量名,不能出现在函数的参数列表中
示例(对应说明3):
def f1():
v = 100
def f2():
v = 200
def f3():
nonlocal v #只对f2里的v进行操作
v = 1
f3()
print("f2最后的v=",v)
f2()
print("f1最后的v=",v)
f1()
示例(对应说明4):
def f1():
v = 100
def f2(v):
nonlocal v #出错,v已经在形参列表中...
v = 1
f2(20)
f1()
lambda表达式(又名匿名函数)
作用:
创建一个匿名函数对象
同def类似,但不提供函数名
语法:
lambda [参数1,参数2,...]: 表达式[]里的内容可以省略
示例:
def myadd(x,y):
return x y
#以上函数可以改写为:
myadd = lambda x,y:x y
print('2 3=',myadd(2,3))
(lambda x:x**2 5)(2)
9
fx = lambda :print("hello")
fx()
等同于:
def fx():
return print("hello")
fx()
语法说明:
1、lambda只是一个表达式,它用来创建一个函数对象
2、当lambda表达式调用时,先执行冒号后(:)的表达式,并返回表达式的结果的引用
3、lambda表达式创建的函数只能包含一条“表达式”
4、lambda比函数简单,且可以随时创建和销毁,有利于减少程序的耦合度
练习:
1、写一个lambda表达式,判断这个数的2次方 1是否能被5整除,如果能整除返回True,否则返回False
fx = lambda n:....
print(fx(3)) # True
print(fx(4)) # False
实现结果如下:
fx = lambda n:(n**2 1) % 5 == 0 # fx = lambda n:True if (n**2 1) % 5 == 0 else False
print(fx(3)) # True
print(fx(4)) # False
2、写一个lambda表达式,求两个变量的最大值:
def mymax(x,y):
...
#或者用lambda
mymax = lambda ...
print(mymax(100,200)) # 200
实现结果如下:
def mymax(x,y):
if x > y:
return x
return y
print(mymax(100,200)) # 200
def mymax(x,y):
return max(x,y) # return x if x > y else y
mymax = lambda x,y:max(x,y) # mymax = lambda x,y:x if x > y else y
print(mymax(100,200)) # 200
3、看懂下面的程序在做什么?
def fx(f,x,y):
print(f(x,y))
fx((lambda a,b:a b),100,200)
fx((lambda a,b:a ** b),3,4)
eval与exec函数
eval()函数
格式:
eval(source,global=None,locals=None)
作用:
把一个字符串当成一个表达式来执行,返回表达式执行后的结果。
示例:
x = 100
y = 200
a = eval('x y')
print(a)
L = eval('list(range(10))')
print(L) # [0,1,2,3,4,5,6,7,8,9]
exec()函数
作用:
把一个字符串当成程序来执行
格式:
exec(source,globals=None,locals=None)
示例:
x = 100
y = 200
s = 'z = x y;print(z);del z; # ;可以写成\n
print("删除成功"'
exec(s) # 执行s绑定的语句
eval和exec的两个参数globals和locals
此两个参数用来设置“表达式”或“程序”运行的全局变量和局部变量
示例:
x = 100
y = 200
s = 'print(x,y,x y)'
exec(s) # 100 200 300
exec(s,{'x':10,'y':20}) # 10,20,30
exec(s,{'x':10},{'x':1,'y':2}) # 1 2 3
exec(s,{'x':10},{'y':2}) # 10 2 12
练习讲解
(1)写一个程序,输入一些单词和解释,将单词作为键,将解释作为值,将这些数据存入字典中,
然后输入查询的单词,显示出此单词的解释。
#方法1--周微--上文写过!
d = {}
while True:
s1= input("请输入一个单词:")
if s1 == '':
break
s2 = input("请输入这个单词的意思:")
if s2 == '':
break
d[s1] = s2
print(d)
while True:
s = input("请输入要查询的单词:")
if s == '':
break
if s not in d:
print("您输入的单词未在字典中找到,请重新输入:")
else:
print(s,"的意思是:",d[s])
#老师方法
dictionary = {}
while True:
k = input("请输入单词(直接回车结束):")
if not k:
break
v = input("请输入解释:")
dictionary[k] = v #形成键值对放入字典
while True:
k = input("请输入要查询的单词:")
if k in dictionary:
print("解释:",dictionary[k])
else:
print("单词不存在")
(2)学生管理项目准备工作:
写一个程序,任意输入n个学生的信息,形成字典后存于列表中:
学生的信息包括:
姓名(字符串)
年龄(整数)
成绩(整数)
循环输入学生信息,直到输入学生姓名为空时结束输入,最后形成字典列表如下:
L = [
{'name':'xiaozhang','age':20,
'score':100},
{'name':'xiaoli','age':21,
'score':98},
{'name':'xiaowang','age':19,
'score':89},
...
]
将以上列表显示如下的表格:
------------- ------ ------
| name | age | score|
| xiaozhang | 20 | 100 |
| xiaoli | 21 | 98 |
| xiaowang | 19 | 89 |
------------- ------ ------
#方法1-周微
L = []
t = ()
s = ''
while True:
name = input("请输入学生的姓名:")
if name == '':
break
age = int(input("请输入学生的年龄:"))
score = int(input("请输入学生的分数:"))
d = {'name':name,'age':age,'score':score}
L = [d]
t = (name,)
print(d)
print(L)
print(t)
m = len(max(t))
print(' ' '-' * (m 2) ' ' '-' * (5) ' ' '-' * (8) ' ')
print('|' 'name'.center(m 2) '|' 'age'.center(5) '|' 'score'.center(8) '|')
for x in L:
for y in x:
s = str(x[y])
if y == 'name':
print('|',s.center(m 1),end = '')
if y == 'age':
print('|',s.center(4),end = '')
if y == 'score':
print('|',s.center(6),'|')
print(' ' '-' * (m 2) ' ' '-' * (5) ' ' '-' * (8) ' ')
#老师做法:
#第一步,读取学生信息,形成字典后存入列表L中
L = []
while True:
name = input("请输入学生姓名:")
if not name:
break
age = int(input("请输入学生的年龄:"))
score = int(input("请输入学生的分数:"))
d = {}
d['name'] = name
d['age'] = age
d['score'] = score
L.append(d)
print(' ---------------- ----- ------- ')
print('| name | age | score |')
for d in L:#d绑定的是字典
t = (d['name'].center(12),
str(d['age'].center(6),
str(d['score'].center(7))
line = "|%s|%s|%s" % t #t是元祖
print(line)
print(' ---------------- ----- ------- ')
练习:
1、写一个函数myfun,此函数用显示连个参数的相关信息
函数:
def myfun(a,b):
此处自己实现
此函数给定两个参数,打印关于两个参数的信息:
(1)打印两个参数的最大值
(2)打印两个参数的和
(3)打印两个参数的积(相乘)
(4)打印从a开始到b结束的所有偶数:
如:
myfun(3,10)
打印如下:
最大值是:10
和是:13
积是:30
3到10之间的偶数是4 6 8
myfun(10,20)
打印...
2、猴子吃桃,有只猴子,摘了很多桃,第1天吃了全部桃子的一半,感觉不饱又吃了一个
第2天吃了剩下的一半,感觉不饱又吃了一个...以此类推
到第10天,发现只剩下一个了
请问第1天摘了多少桃?
3、完全数:
1 2 3 = 6 (6为完全数)
1,2,3都为6的因数(能被一个数x整除的)
1 x 6 = 6
2 x 3 = 6
完全数是指除自身以外,所有的因数相加之和等于自身的数
求4~5个完全数并打印
答案:
6
28
496
...
结果如下:
---1-----
def myfun(a,b):
print('最大值是:',max(a,b))
print('和是:',a b)
print('积是:',a * b)
i = a
while i < b:
if i % 2 == 0:
print(i)
i = 1
myfun(3,10)
---2-----
def get_lastday(y):
#根据今天的桃子数y,计算昨天的桃子树x
x = (y 1) * 2
return x
p = 1 #第十天的桃子数
day = 10 #用来表示当前是第几天
while day > 1:
day -= 1
p = get_lastday(p)
print("第",day,"天的桃子是:",p)
---3-----
i = 1 # 完全数的开始值
while True:
# 判断是否是完全数,如果是则打印
L = []
for x in range(1,i):
if i % x == 0: #如果x是i的因数
L.append(x) #放在列表中
#此时L列表是i所有的因数
if sum(L) == i:
print(i,"是完全数")
i = 1
#方法2,用函数来求完全数,增加程序的可读性
def main():
#此函数计算所有的完全数
i = 1 # 完全数的开始值
while True:
# 判断是否是完全数,如果是则打印
if is_perfect_number(i):
print(i,"是完全数")
i = 1
def is_perfect_number(i):
L = [] #每次循环开始都创建一个新列表,用来存因数
for x in range(1,i):
if i % x == 0: #如果x是i的因数
L.append(x) #放在列表中
#此时L列表是i所有的因数
if sum(L) == i:
return True
return False
main()
day11-------------2019-10-17----------------------------------------------------------
函数式编程
函数式编程是指用一系列函数决定问题
函数是一等公民
函数本身可以赋值给变量,赋值后变量绑定函数
允许将函数本身作为参数传入另一个函数
允许返回一个函数
print(sum(range(1,101)))
函数的可重入性
可重入是指一个函数传的参数一定,则结果必须一定
要求:
def 定义的函数不要访问除局部变量以外的变量
示例:
#以下是不可重入的函数
y = 200
def myadd(x):
return x y
print(myadd(10)) # 210
y = 300
print(myadd(10)) # 310
#以下是可重入的函数
def myadd(x,y):
return x y
print(myadd(10,20)) # 30
map函数
高阶函数 High Order Function
什么是高阶函数:
满足下列条件的函数即为高阶函数:
1、函数接受一个或多个函数作为参数传入
2、函数返回一个函数
示例:
def f1(fx,x,y):
return fx(x,y)
python中内建(builtins)的高阶函数
map filter sorted
map函数:
map(func,*iterables)用函数和可迭代对象中的每一个元素作为参数计算出新的可迭代
对象,当最短的一个可迭代对象不再提供数据时,此可迭代对象生成结束。
示例:
def pow2(x):
return x**2
for x in map(pow2,range(1,10)):
print(x)
内建 pow(x,y,None)
# 生成 1**4 ,2**3, 3**2 ,4**1
for x in map(pow,range(1,10),range(4,0,-1)):
print(x)
for x in map(pow,[2,3,5,7],[4,3,2,1],range(5,10)):
print(x)
练习:
1、求1**2 2**2 3**2 ... 9**2的和
2、求1**3 2**3 3**3 ... 9**3的和
3、求1**9 2**8 3**7 ... 9**1的和
1------------------------------------------
#方法1
s = 0
for x in range(1,10):
s = x**2
print(s)
#方法2
def pow2(x)
return x**2
print(sum(map(pow2,range(1,10))))
#方法3
print(sum(map(lambda x:x**2,range(1,10))))
2------------------------------------------
print(sum(map(lambda x:x**3,range(1,10))))
3------------------------------------------
print(sum(map(pow,range(1,10),range(9,0,-1))))
filter与sorted函数
filter函数:
格式:
filter(func,iterable)
作用:
筛选可迭代对象iterable中的数据,返回一个可迭代对象,此可迭代对象将对iterable进行筛选
说明:
函数func将对每个元素进行求值,返回False则将此数据丢弃,返回True则保留此数据
示例:
def isodd(x):
return x % 2 == 1
for x in filter(isodd,range(10)):
print(x)
even = [x for x in
filter(lambda x: x%2==0,
range(10))]
练习:
1、将1-20内的偶数用filter筛选出来,形成列表
2、用filter函数将1-100之间的所有素数(prime)放入列表中
实现结果如下:
1--------------------
#方法1
L = [x for x in filter(lambda x:x % 2 ==0,range(1,20))]
print(L)
#方法2
L = list(filter(lambda x:x % 2 == 0,range(1,20)))
print(L)
2-------------------
L = list(filter(isprime,range(100)))
print(L)
sorted函数
作用:
将原可迭代对象的数据进行排序,生成排序后的列表。
格式:
sorted(iterable,key=None,reverse=False)
说明:
iterable可迭代对象
key 函数是用来提供一个参考值,这个值作为排序的依据
reverse标志用来设置是否降序排序
示例:
L = [5,-2,-4,0,3,1]
L2 = sorted(L)
print(L2)
# L = [-4,-2,0,1,3,5]
L3 = sorted(L,key = abs)
print(L3)
# L = [0,1,-2,3,-4,5]
names = ['Tom','Jerry','Spike','Tyke']
L4 = sorted(names)
L5 = sort(names,key = len) #按照字符串的长度排序
#按字符顺序排序,不区分大小写
def f(ch):
code = ord(ch) #得到编码
if (97 26) > code >= 97:
code -= 32
return code
sorted('ACDacbdE',key=f)
#['A','a','b','C','c','D','d','E']
练习:
1、names = ['Tom','Jerry','Spike','Tyke']
让names排序,排序的依据是字符串的反序
'moT' 'yrreJ' 'ekipS' 'ekyT'
L2 = sorted(names,...)
排序后
L2 = ['Spike','Tyke','Tom','Jerry']
实现如下:
names = ['Tom','Jerry','Spike','Tyke']
def fx(name):
return name[::-1]
L2 = sorted(names,key=fx)
print(L2)
或者用lambda
L2 = sorted(names,key=lambda n: n[::-1])
2、写一个函数input_student()得到学生的姓名,成绩,年龄(用之前写的函数)
L = input_student() #输入一些学生信息
print("按年龄从大到小排序后")
L2 = sorted(L,.....)
output_student(L2)
print("按成绩从高到低排序后")
L3 = sorted(L,.....)
output_student(L3)
实现如下:
#此函数获取学生信息,并返回学生信息的字典的列表
def input_student():
L = []
#d = {} 此处所有学生共用一个字典,会出错
while True:
name = input("请输入学生姓名:")
if not name:
break
age = int(input("请输入学生年龄:"))
score = int(input("请输入学生成绩:"))
d = {} #重新创建一个新的字典
d['name'] = name
d['age'] = age
d['score'] = score
L.append(d)
return L
def output_student():
#以表格形式再打印学生信息
print(' ------------ ------ -------- ')
print('| name | age | score |')
print(' ------------ ------ -------- ')
for d in L: #d绑定的是字典
t = (d['name'].center(12),str(d['age']).center(6),str(d['score']).center(7))
line = "|%s|%s|%s" % t # t是元祖
print(line)
print(' ------------ ------ -------- ')
L = input_student()
output_student(L)
print("再添加几个学生信息")
L = input_student()
print("添加学生后的学生信息如下:")
output_student(L)
L = input_student() #输入一些学生信息
print("按年龄从大到小排序后")
def get_age(d): #d为字典
return d['age']
L2 = sorted(L,key=get_age,reverse=True)
output_student(L2)
print("按成绩从高到低排序后")
L3 = sorted(L,key=lambda d: d['score'],reverse=True)
output_student(L3)
递归函数 recursion
函数直接或间接的调用自身
示例:
import time
def story():
time.sleep(1)
print("从前有座山,山里有座庙,庙里有个老和尚,他在干什么,他在讲故事,他在讲:")
story()
递归说明:
1、递归一定要控制递归的层数,当符合某一个条件时要终止递归。
2、几乎所有的递归都能用while循环来代替
控制递归的层数示例:
def fx(n):
print("递归进入第",n,"层")
if n == 3:
return
fx(n 1)
print("递归退出第",n,'层')
fx(1)
print("程序结束")
递归进入第1层
递归进入第2层
递归进入第3层
递归退出第2层
递归退出第1层
程序结束
递归的优缺点:
优点:
递归可以把问题简单化,让思路更为清晰,代码更简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果
递归最大深度1000
递归函数的实现方法:
先假设函数已经实现
求和 1 2 3 ... 100的和
def mysum(x):
if x <= 1: # 设置递归的终止点
return 1
return x mysum(x-1)
v = mysum(100)
print(v)
练习:
编写程序用递归用阶乘:
def myfac(x):
...
print(myfac(5)) # 120
print(myfac(4)) # 24
实现如下:
def myfac(x):
if x <= 1: # 设置递归的终止点
return 1
return x * myfac(x -1)
print(myfac(5)) # 120
print(myfac(4)) # 24
闭包 closure
将内嵌函数的语句和这些语句的执行环境打印在一起时,得到的对象称为闭包。
闭包必须满足三个条件:
1、必须有一个内嵌函数
2、内嵌函数必须引用外部函数中的变量
3、外部函数返回值必须是内嵌函数
示例:
def make_power(y):
def fx(arg):
return arg ** y
return fx
pow2 = make_power(2)
print("3的平方是:",pow2(3)) #3的平方是:9
pow3 = make_power(3)
print("3的立方是:",pow3(3)) #3的立方是:27
示例:
用参数返回相应的数学函数的示例
# y = a*x**2 b*x c
def make_function(a,b,c):
def fx(x):
return a*x**2 b*x c
return fx
#创建一个 y = 4x2 5x 6的函数用fx1绑定
fx1 = make_function(4,5,6)
print(fx1(2)) #求在x等2时y的值
练习讲解
1、写一个函数mysum,要求给出一个数n,求 1 2 3 4 ..... n的和
如:
print(mysum(100)) # 5050
print(mysum(10)) # 55
实现如下:
def mysum(n):
s = 0
for x in range(1,n 1):
s =x
return s 或者 return sum(range(1,n 1))
print(mysum(100))
print(mysum(10))
2、写一个函数myfac(n)来计算n!(n的阶乘)
n!=1*2*3*4...*n
如:
print(myfac(5)) # 120
print(myfac(4)) # 24
实现方法:
def myfac(n):
s = 1
for x in range(2,n 1):
s*=x
return s
print(myfac(5))
print(myfac(4))
3、写一个函数,求
1 2**3 3**3 ... n**n的和 (n给个小点的数)
实现如下:
def power_sum(n):
s = 0
for x in range(1,n 1):
s = x**x
return s
或者
return sum(map(lambda x:x**x,range(1,n 1)))
4、修改之前的学生信息管理程序,实现添加菜单和选择菜单操作功能:
菜单:
---------------------------------------
| 1)添加学生信息 |
| 2)查看所有学生信息 |
| 3)修改学生的成绩 |
| 4)删除学生信息 |
| q)退出 |
---------------------------------------
请选择:1
请输入姓名:....
请选择:3
请输入修改学生的姓名:...
(要求:每个功能都对应一个函数)
写一个打印菜单的函数
def show_menu():
print(' -------------------- ')
print('| 1)添加学生信息 |')
print('| 2)查看所有学生信息 |')
print('| 3)修改学生的成绩 |')
print('| 4)删除学生信息 |')
print('| q)退出 |')
print(' -------------------- ')
def main():
docs = [] #此列表用来存储所有学生信息的字典
while True:
show_menu()
s = input("请选择:")
if s == '1':
docs = input_student()
elif s == '2':
output_student(docs)
elif s == '3':
modify_student_info(docs)
elif s == '4':
delete_student_info(docs)
elif s == 'q':
return 结束此函数执行,直接退出
#此函数用来修改学生的信息
def modify_student_info(lst):
name = input("请输入要修改学生的姓名:")
for d in list:
if d['name'] == name:
score = int(input("请输入新的成绩:"))
d['score'] = score
print("修改",name,'的成绩为:',score)
return
else:
print("没有找到名为:",name,'的学生信息')
#定义一个删除学生信息的函数
def delete_student_info(lst):
name = input("请输入要删除学生的姓名:")
for i in range(len(lst)): #从0开始把所有索引取出来
if lst[i]['name'] == name:
del lst[i]
print("已成功删除:",name)
return True
else:
print("没有找到名为:",name,"的学生")
main()
5、编写函数求阶乘myfac(x),用什么方法都可以
6、写程序算出1-20的阶乘的和
1! 2! 3! ...... 20!
我的做法:
#求n!阶乘
def myfac(n):
m = 1
for i in range(0,n):
m *= (n-i)
print(m)
myfac(1)
myfac(2)
myfac(3)
myfac(4)
print("--------------------")
#求1! 2! ...20!
def myfac1(n):
s = 0
for x in range(1,n 1):
m = 1
for i in range(0,x):
m *= (x-i)
s = m
print(n,'!=',s)
myfac1(3)
print("---------------------")
myfac1(20)
7、改写之前学生信息管理程序,添加如下四个功能
按成绩从高到低打印学生信息
按成绩从低到高打印学生信息
按年龄从大到小打印学生信息
按年龄从小到大打印学生信息
(要求原来输入的列表顺序保持不变)
8、已知有列表:
L = [[3,5,8],10,[[13,14],15,18],20]
写一个函数print_list(lst)打印出所有元素
写一个函数sum_list(lst)返回这个列表中所有元素的和
注:type(x) 可以返回一个变量的类型
如: type(20) is int #返回True
type([1,2,3]) is list #返回True
--------------2019-10-23---day12-------------------------------------------------------
装饰器(专业提高篇)
函数装饰器是指装饰的一个函数,传入的是一个函数,返回的也是一个函数的函数
函数装饰器的语法:
def 装饰器函数名(参数):
语句块
return 函数对象
被装饰函数的语法
@装饰器函数名
def 函数名(形参列表):
语句块
示例1:
@mydeco 等同于 myfunc = mydeco(myfunc)
def myfunc():
print("myfunc被调用")
myfunc()
def mydeco(fn):
def fx():
print(" ")
fn()
print("------------")
return fx
打印结果如下:
myfunc被调用
------------
示例2:
@mydeco 等同于 myfunc = mydeco(myfunc)
def myfunc():
print("myfunc被调用")
myfunc()
def mydeco(fn):
def fx():
print("fx被调用")
return fx
打印结果如下:
fx被调用
装饰器应用案例
带有参数的装饰器及应用案例
#此示例带有参数的装饰器及应用案例
银行业务:
存钱
savemoney
取钱
withdraw
@privileged_check
@message_send
def savemoney(name,x):
print(name,"存钱",x,'元')
@message_send
def withdraw(name,x):
print(name,"取钱",x,'元')
#以下是调用者小张定的程序
savemoney('小李',200)
savemoney('小赵',500)
withdraw('小王',300)
添加一个余额变动短消息功能
def message_send(fn):
def fx(name,x):
print("发送消息:",name,'来银行办理业务')
fn(name,x)
print("发送消息:",name,'办了',x,'元的业务...')
return fx
添加一个权限验证功能的装饰器
def privileged_check(fn):
def fx(name,x):
print("正在检查权限...")
if True:
fn(name,x)
return fx
函数文档字符串、属性
函数内部,第一个没有赋值给任何变量的字符串为文档字符串
语法:
def 函数名(形参列表):
''' 函数的文档字符串 '''
函数语句块
示例:
def cba():
'这是一块文档字符串...'
pass
>>> help(cba)
函数的_doc_属性
_doc_属性用于绑定该函数的文档字符串
示例:
def fx(a,b):
'''这是函数的文档字符串
这是第二行...
'''
print(fx._doc_)
函数的_name_属性:
_name_属性用于绑定函数名的字符串
示例:
def fx():
pass
f1 = fx
print(f1._name_)
函数定义语句(def语句的语法)
[@装饰器名1]
[@装饰器名2]
...
def 函数名([位置形参],[*[元组形参名]],[命名关键字形参],[**字典形参]):
'''文档字符串'''
语句块
注意:[]里的内容代表可省略
面试题:
L = [1,2,3]
def f(n,lst=[]):
lst.append(n)
print(lst)
f(4,L)
f(5,L)
f(100)
f(200)
#以上结果是什么?为什么?
[1,2,3,4]
[1,2,3,4,5]
[100]
[100,200]
说明:
默认参数(缺省参数)
绑定在函数对象内部,具随函数的生命一直存在
解决办法:
L = [1,2,3]
def f(n,lst=None):
if lst is None:
lst = []
lst.append(n)
print(lst)
f(4,L)
f(5,L)
f(100)
f(200)
结果如下:
[1,2,3,4]
[1,2,3,4,5]
[100]
[200]
模块
多人写一个程序时该怎么做?
模块 Module
什么是模块?
模块是一个包含有一系列数据、函数、类等组成的程序组
模块是一个文件,模块文件名通常以.py结尾
作用:
让一些相关的数据、函数、类等有逻辑的组织在一起,使
逻辑结构更加清晰。
模块中的数据、函数、类等可提供给其他模块或程序使用
模块的分类:
1、内置模块(builtins),在解析器的内部可以直接使用。(len,max,min...)
2、标准库模块,安装python时已安装且可直接使用。
3、第三方模块(通常为开源),需要自己安装。
4、用户自己完成的模块(可以作为其他人的第三方模块)即自定义模块
python3是用c语言写的,内置模块很多都是c语言写的
import语句
语法:
import 模块名1 [as 模块新名1][,模块名2 [as 模块新名2]],...
示例:
# 导入数学模块
import math
# 导入系统模块sys和os模块
import sys,os
作用:
将某模块整体导入到当前模块
用法:
模块.属性名
dir(obj) 函数返回模块所有属性的字符串列表
help(obj) 可以查看模块相关的文档字符串
练习:
1、输入一个正方形的周长,输出正方形的面积
2、输入一个圆的半径,打印出这个圆的面积
3、输入一个正方形的面积,打印这个正方形的周长
(要求:用math模块内的函数和数据)
实现如下:
import math
length = float(input("请输入正方形的周长:"))
area = math.pow(length/4,2)
print("此正方形的周长为:",area)
r = float(input("请输入圆的半径:"))
area = math.pow(r,2)*math.pi
print("此圆的面积是:",area)
area = float(input("请输入正方形的面积:"))
length = math.sqrt(area)*4
print("此正方形的周长是:",length)
修改如下:
import math as m
length = float(input("请输入正方形的周长:"))
area = m.pow(length/4,2)
print("此正方形的周长为:",area)
r = float(input("请输入圆的半径:"))
area = m.pow(r,2)*m.pi
print("此圆的面积是:",area)
area = float(input("请输入正方形的面积:"))
length = m.sqrt(area)*4
print("此正方形的周长是:",length)
修改如下:
from math import pi,pow,sqrt
length = float(input("请输入正方形的周长:"))
area = pow(length/4,2)
print("此正方形的周长为:",area)
r = float(input("请输入圆的半径:"))
area = pow(r,2)*pi
print("此圆的面积是:",area)
area = float(input("请输入正方形的面积:"))
length = sqrt(area)*4
print("此正方形的周长是:",length)
from import语句、dir函数
语法:
from 模块名 import 模块属性名1 [as 属性新名1][,模块属性名2[as 属性新名2],...]
作用:
将某模块内的一个或多个属性导入到当前模块的作用域
示例:
from math import pi
from math import pow,sqrt
from math import factorial as fac
from import *语句
语法:
from 模块名 import *
作用:
将某模块的所有属性都导入到当前模块
示例:
from math import *
dir函数:
dir ([对象]) 返回一个字符串列表
作用:
如果没有参数调用,则返回当前作用域内的所有变量的列表
如果给定一个对象作为参数,则返回这个对象的所有变量的列表
1、对于一个模块,返回这个模块的全部属性
2、对于一个类对象,返回类对象的所有变量,亲递归基类对象
的所有变量
3、对于其他对象,返回所有的变量、类变量、基类变量
import math
from math import factorial
from math import *
数学模块、时间模块
数学模块math
模块名math
python内建模块大概有两百多个
时间模块
此模块提供了时间相关的函数,且一直可用
公元纪年:0000.1.1 0时
计算机元年:1970.1.1 0时
UTC时间
DST阳光节约时间,夏令时,基本不用
from time import *
>>> print(time.localtime())
time.struct_time(tm_year=2019, tm_mon=10, tm_mday=26, tm_hour=20, tm_min=30, tm_
sec=52, tm_wday=5, tm_yday=299, tm_isdst=0)
示例:
import time
print("开始打印")
time.sleep(10)
print("结束打印")
t = time.gmtime()
t [0:3] 打印出UTC 年月日
time.asctime((2018,12,31,1,1,0,0,0,0))
练习:
1、写一个程序,输入你的出生日期
(1)算出你已经出生了多少天?
(2)算出你出生那天是星期几?
实现方法如下:
year = int(input("请输入年:"))
month = int(input("请输入月:"))
day = int(input("请输入日:"))
#得到出生时的秒数
birthday_second = time.mktime((year,month,day,0,0,0,0,0,0))
#得到当前时间的秒数
cur_second = time.time()
s = cur_second - birthday_second
print("您已经出生:",s/60/60//24,'天')
birthday = (year,month,day,0,0,0,0,0,0)
转为秒数
s = time.mktime(birthday)
转回到时间本地元组
t = time.localtime(s)
weekday = {0:"星期一",1:"星期二",2:"星期三",3:"星期四",4:"星期五",5:"星期六",6:"星期日"}
print("您出生那天是:",weekday[t[6]])
练习讲解
编写函数求阶乘myfac(x),用什么方法都可以
1、写程序算出1-20的阶乘的和
1! 2! 3! ...... 20!
我的做法:
#求n!阶乘
def myfac(n):
m = 1
for i in range(0,n):
m *= (n-i)
print(m)
myfac(4)
print("--------------------")
#求1! 2! ...20!
def myfac1(n):
s = 0
for x in range(1,n 1):
m = 1
for i in range(0,x):
m *= (x-i)
s = m
print(n,'!=',s)
myfac1(3)
print("---------------------")
myfac1(20)
老师做法:
def myfac(x):
s = 1
for i in range(2,x 1):
s*=i
return s
print(sum(map(myfac,range(1,21))))
2、改写之前学生信息管理程序,添加如下四个功能
按成绩从高到低打印学生信息
按成绩从低到高打印学生信息
按年龄从大到小打印学生信息
按年龄从小到大打印学生信息
(要求原来输入的列表顺序保持不变)
老师做法:
写一个打印菜单的函数
def show_menu():
print(' -------------------------------- ')
print('| 1)添加学生信息 |')
print('| 2)查看所有学生信息 |')
print('| 3)修改学生的成绩 |')
print('| 4)删除学生信息 |')
print('| 5)按成绩从高到低打印学生信息 |')
print('| 6)按成绩从低到高打印学生信息 |')
print('| 7)按年龄从大到小打印学生信息 |')
print('| 8)按年龄从小到大打印学生信息 |')
print('| q)退出 |')
print(' -------------------------------- ')
def main():
docs = [] #此列表用来存储所有学生信息的字典
while True:
show_menu()
s = input("请选择:")
if s == '1':
docs = input_student()
elif s == '2':
output_student(docs)
elif s == '3':
modify_student_info(docs)
elif s == '4':
delete_student_info(docs)
elif s == '5':
print_by_score_desc(doc)
elif s == '6':
print_by_score_asc(doc)
elif s == '7':
print_by_age_desc(doc)
elif s == '8':
print_by_age_asc(doc)
elif s == 'q':
return 结束此函数执行,直接退出
#此函数用来修改学生的信息
def modify_student_info(lst):
name = input("请输入要修改学生的姓名:")
for d in list:
if d['name'] == name:
score = int(input("请输入新的成绩:"))
d['score'] = score
print("修改",name,'的成绩为:',score)
return
else:
print("没有找到名为:",name,'的学生信息')
#定义一个删除学生信息的函数
def delete_student_info(lst):
name = input("请输入要删除学生的姓名:")
for i in range(len(lst)): #从0开始把所有索引取出来
if lst[i]['name'] == name:
del lst[i]
print("已成功删除:",name)
return True
else:
print("没有找到名为:",name,"的学生")
#按成绩从高到低打印学生信息
def print_by_score_desc(lst):
L = sorted(lst,key=lambda d: d['score'],reverse=True)
ouput_student(L)
#按成绩从低到高打印学生信息
def print_by_score_asc(lst):
L = sorted(lst,key=lambda d: d['score'])
ouput_student(L)
#按年龄从大到小打印学生信息
def print_by_age_desc(lst):
L = sorted(lst,key=lambda d: d['age'],reverse=True)
ouput_student(L)
#按年龄从小到大打印学生信息
def print_by_age_asc(lst):
L = sorted(lst,key=lambda d: d['age'])
ouput_student(L)
main()
3、已知有列表:
L = [[3,5,8],10,[[13,14],15,18],20]
写一个函数print_list(lst)打印出所有元素
写一个函数sum_list(lst)返回这个列表中所有元素的和
注:type(x) 可以返回一个变量的类型
如: type(20) is int #返回True
type([1,2,3]) is list #返回True
L = [[3,5,8],10,[[13,14],15,18],20]
def print_list(lst):
fox x in lst: #x可能绑定列表,也可能绑定整数
if type(x) is list:
print_list(x)
else:
print(x)
def sum_list(lst):
s = 0
for x in lst:
if type(x) is list:
s = sum_list(x)
else:
s = x
return s
print_list(L)
print("和是:",sum_list(L))
预留练习:
1、写一个程序,以电子时钟格式打印时间:
时间格式:
HH:MM:SS
时间每隔一秒刷新一次
2、编写一个闹钟程序,启动时设置定时时间,到时候后打印出一句话,然后程序退出
3、请编写函数fun,功能是计算下列多项式的和
sn = 1 1/1! 2/2! 3/3! ... n/n!
计算n为100的值。
看一下求出来的和是什么?
(建议用math.factorial)
4、把学生管理系统划分为模块(把相关操作放在一个模块内):
建议:
main.py放主事件循环
menu.py放show_menu函数
student_info.py放学生信息相关的操作
-------------2019-10-25---------------day13-------------------------------------------
系统模块sys
此模块全部是运行时系统相关的信息
sys.path 模块搜索路径
sys.module
sys.version
sys.version_info
sys.platform
sys.argv 绑定用户启动程序时命令行参数的列表
sys.copyright
sys.builtin_module_names
sys.exit([arg]) 退出程序
sys.getrecursionlimit() #1000,递归嵌套层次限制(栈的深度)调用次数
sys.setrecuisionlimit(2000) #修改递归嵌套层次限制
import sys
if sys.version[0] = '2':
print("我运行在python2中")
elif sys.version[0] = '3':
print("我运行在python3中")
if sys.version_info[0] = '2':
print("我运行在python2中")
elif sys.version_info[0] = '3':
print("我运行在python3中")
print("当前的主版本号是:",sys.version_info.major
"当前的次版本号是:",sys.version_info.minor
"当前的微版本号是:",sys.version_info.micro)
print("当前的操作系统是:".sys.platform)
def f():
print("f开始调用")
import sys
sys.exit(0)
print("f调用结束")
f()
print("结束程序")
#结果:f开始调用
自定义模块
自定义的模块名必须符合“标识符”的命名规则(同变量名)
模块有各自独立的作用域
示例:
mymod1.py
此模块是用户自定义模块
假设小张写了此模块
def myfun1():
print("正在调用mymod1里面的myfun1()")
def myfun2():
print("mymod1里的myfun2()")
name1 = 'audi'
name2 = 'zhangsan'
06_test_mymod1.py
#此程序用于示意导入小张写的模块mymod1
#并调用相应的数据和函数
import mymod1 #导入模块mymod1.py
mymod1.myfun1() #调用mymod1里的myfun1()函数
print(mymod1.name1) # audi
from mymod1 import name2
print("mymod1里的name2为:",name2)
from mymod1 import *
myfun2()
示例:
此示例示意各模块内的变量不会冲突
import mymod1
import mymod2
print('mymod1.name1=',mymod1.name1)
print('mymod2.name1=',mymod2.name1)
以下方法使用,会引起变量冲突
from mymod1 import *
from mymod2 import *
print(name1) # 已经发生冲突
模块化编程的优点:
1、有利于多人合作开发
2、使代码更容易维护
3、提高代码的复用率
4、有利于解决变量名冲突问题
模块的加载与导入
import语句 搜索模块的路径顺序
1、搜索程序运行时的路径(当前路径)
2、sys.path提供的路径
3、搜索内置模块
sys.path是一个存储模块搜索路径的列表
(1)可以把自定义的模块放在相应的路径下就可以导入
(2)可以把自己模块的路径添加在sys.path列表中
import sys
sys.path.append('/home/tarena')
import mymod3
mymod3.myfun3()
模块的加载过程:
1、在模块导入时,模块的所有语句会执行
2、如果一个模块已经导入,则再次导入时不会重执行模块内的语句
模块的重新加载:
def myfun1():
print("正在调用mymod3里面的myfun1()")
def myfun2():
print("mymod3里的myfun2()")
def myfun4():
print("mymod3里的myfun4()")
import mymod3
import imp
imp.reload(mymod3)
mymod3.fun4()
模块导入和执行的过程:
1、先搜索相关的路径找模块(.py)
2、判断是否有模块对应的.pyc文件,如果存在pyc文件且比py文件新,则直接
加载.pyc文件
3、否则用.py文件生成,.pyc后再进行加载
pyc模块的编译文件
mymod1.py---编译--->mymod1.pyc---解释执行--->python3
模块的属性
属性的实质是变量(是模块内的全局变量)
模块内预置的属性
_doc_属性
作用:
用来绑定模块的文档字符串
模块内第一个没有赋值给任何变量的字符串为模块的文档字符串
# mymod4.py
'''这是模块的文档字符串的标题
这是文档字符串的内容
此模块包含两个函数和两个变量
'''
def f1():
pass
print(_doc_)
import mymod4
help(mymod4)
dir(mymod4)
_file_属性
绑定模块对应的文档路径名
1、对于内建模块,不绑定路径
2、对于其他模块,绑定路径名的字符串
_name_属性
此属性用来记录模块的自身名字
1、记录模块名
2、用来判断是否为主模块(最先运行的模块)
说明:
当此模块为主模块时,_name_绑定 '_main_'
当此模块不是主模块时,此属性绑定模块名
mymod5.py
def f1():
print("f1被调用")
if _name_ == '_main_':
print("mymod5.py正在当做主模块运行")
f1()
else:
print("mymod5.py正在被其他模块导入")
print("模块名为:",_name_)
这种情况下:mymod5.py正在被其他模块导入
import mymod5
mymod5.f1()
模块的_all_列表
用来存放可导出属性的字符串列表
作用:
当用from import * 语句导入时,只导入_all_列表内的属性
mymod6.py
#限制用from mymod6 import *时只导入f1,var1
_all_ = ['f1','var1']
def f1():
pass
def f2():
pass
def f3():
pass
var1 = 'hello'
var2 = 'world'
import mymod6
from mymod6 import *
dir()
模块的隐藏属性
模块中以'_'开头的属性,在from import * 语句导入时,将不被导入,
通常称这些属性为隐藏属性
示例:mymod7
def f1():
pass
def _f2(): #在from import * 语句导入时,将不被导入
pass
var1 = '变量1'
_var2 = '变量2' #在from import * 语句导入时,将不被导入
from mymod7 import *
dir()
随机模块 random
作用:
用于模拟或生成随机输出的模块
import random
R.random() 返回一个[0,1)之间的随机实数
R.uniform(a,b) 返回[a,b)区间内的随机实数
R.randrange([start,]stop[,step])返回range(start,stop,step)中的随机数
R.choice(seq)从序列中返回随意元素
R.shuffle(seq[,random])随机指定序列的顺序
R.sample(seq,n)
练习:
猜数字游戏:
随机生成0-100之间的数用变量x绑定,循环让用户输入一个数用y绑定
1、如果y==x,则提示“您猜对了”,打印出猜测的次数并退出
2、如果y<x则提示“您猜小了”,然后继续猜
3、如果y>x则提示“您猜大了”,然后继续猜,猜对后程序退出并打印次数。
实现如下:
import random
x = random.randrange(101)
print(x)
times = 0
while True:
y = int(input("请输入:"))
times = 1
if x == y:
print("您猜对了")
break
elif y < x:
print("您猜小了")
elif y > x:
print("您猜大了")
print("您一共猜了%d次" % times)
包、包的导入
包(模块包)package
包是将模块以文件夹的组织形式进行分组管理的方法
作用:
将一系列模块进行分类管理,有利于防止命名冲突
可以在需要时加载一个或部分模块而不是全部模块
包示例:
mypack/
_init_.py
menu.py
games/
_init_.py
contra.py
supermario.py
tanks.py
office/
_init_.py
excel.py
word.py
_init_.py文件
常规包内必须存在的文件
_init_.py会在包加载时被自动调用
作用:
编写此包的内容
在内部填写文档字符串
在_init_.py内可以加载此包依赖的一些其他模块
包的导入
用三条import语句可以导入包(同模块的导入规则)
import 包名 [as 包别名]
import 包名.模块名 [as 模块新名]
import 包名.子包名.模块名
from 包名 import 模块名 [as 模块新名]
from 包名.子包名 import 模块名 [as 模块新名]
from 包名.子包名.模块名 import 属性名 [as 属性新名]
from 包名 import *
from 包名.模块名 import *
...
all列表
包_init_.py 内的_all_列表
作用:
用来记录此包中有哪些子包或模块在用from 包 import *语句导入时是否被调入
说明:
_all_列表只对form import * 语句起作用
示例:
在_init_.py内写入
_all_ = ['包名1','包名2'] 代表导入时候加载这两个包
作业讲解
1、写一个程序,以电子时钟格式打印时间:
时间格式:
HH:MM:SS
时间每隔一秒刷新一次
实现如下:
import time
def clock():
while True:
cur_time = time.localtime()
t_hms = cur_time[3:6] #得到时分秒元组
print("%02d:%02d:%02d" % t_hms,end='\r')
time.sleep(1)
clock()
2、编写一个闹钟程序,启动时设置定时时间,到时后打印出一句话,然后程序退出
实现如下:
import time
def alarm(hour,minute):
while True:
cur_time = time.localtime()
tuple_hm = cur_time[3:5]
print("%02d:%02d:%02d" % cur_time[3:6],end='\r')
if (hour,minute) == tuple_hm:
break
def main():
h = int(input("请输入小时:"))
m = int(input("请输入分钟:"))
alarm(h,m)
print("时间到...")
main()
>>> print(time.localtime())
time.struct_time(tm_year=2019, tm_mon=10, tm_mday=26, tm_hour=20, tm_min=30, tm_
sec=52, tm_wday=5, tm_yday=299, tm_isdst=0)
3、请编写函数fun,功能是计算下列多项式的和
sn = 1 1/1! 1/2! 1/3! ... 1/n!
计算n为100的值。
看一下求出来的和是什么?
(建议用math.factorial)
实现如下:
import math
def fun(n):
formula = lambda x: 1 / math.factorial(x)
return sum(map(formula,range(n 1)))
print("n=100时,fun(100)=",fun(100))
4、把学生管理系统划分为模块(把相关操作放在一个模块内):
建议:
main.py放主事件循环
menu.py放show_menu函数
student_info.py放学生信息相关的操作
5、模拟斗地主发牌,牌共54张,黑桃('\u2660'),梅花('\u2663'),方块('\u2665'),
红桃('\u2666')
大小王:A2 - 10JQK
三个人玩,每个人发17张牌,底牌留三张
操作:
输入回车:打印第一个人的17张牌
输入回车:打印第二个人的17张牌
输入回车:打印第三个人的17张牌
输入回车:打印三张底牌
2019-10-27---------------day14-------------------------------------------
包的相对导入、加载路径
包的相对导入是指包内模块的相互导入
语法:
from 相对路径包或模块import属性或模块名
或
from 相对路径包或模块import *
相对路径:
.代表当前目录
..代表上一级目录
...代表上二级目录
....以此类推
注:相对导入时不能超出包的外部
包的加载路径:
同模块的加载路径相同
1、当前文件夹
2、sys.path给出的路径
异常
异常except
什么是错误
错误是指由于逻辑或语句等导致一个程序无法正常执行的问题
特点:
有些错误是无法预知的
什么是异常
异常时程序出错时标识的一种状态
当异常发生时,程序不会再向下执行,而转为调用此函数的方待处理此错误
并恢复为正常状态
异常的作用:
1、通知上层调用者有错误产生需要处理
2、用作信号
try except语句
try except语句
语法:
try:
可能触发异常的语句
except 错误类型1 [as 变量1]:
异常处理语句1
except 错误类型2 [as 变量2]:
异常处理语句2
except (错误类型3,错误类型4...) [as 变量3:]:
异常处理语句3
...
except:
异常处理语句other
else:
未发生异常时执行的语句
finally:
最终执行语句
作用:
尝试捕获异常,将程序转为正常状态并继续执行
语法说明:
as 子句是用于绑定错误对象的变量,可以省略不写
except 子句可以有一个或多个,但至少要有一个
else 子句最多只有一个,也可以省略不写
finally 子句做多只能有一个,也可以省略不写
示例:
03_try_except.py
def div_apple(n):
print("%d个苹果想分给几个人?" % n)
s = input("请输入人数:")
cnt = int(s) #坑你触发ValueError错误异常
#以下一行可能触发ZeroDivisionError错误异常
result = n / cnt
print("每个人分了",result,'个苹果')
#以下是调用
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
改写---------------------------------------------------:
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except ValueError:
print('div_apple内出现了ValueError错误,已处理')
print('用户输入不合法,苹果退回来不分了')
except ZeroDivisionError:
print('出现被零除的错误!,苹果不分了')
print("程序正常退出")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except ValueError:
print('div_apple内出现了ValueError错误,已处理')
print('用户输入不合法,苹果退回来不分了')
except:
("除ValueError外,其他错误类型都被捕获")
print("程序正常退出")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except (ValueError,ZeroDivisionError):
print('苹果退回来不分了')
print("程序正常退出")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except ValueError as err:
print('苹果退回来不分了')
print('错误信息是:',err)
print("程序正常退出")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except:
print('错误已经被捕获')
else:
print("程序正常执行,没有异常")
print("程序正常退出")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except:
print('错误已经被捕获')
else:
print("程序正常执行,没有异常")
finally:
print("我是finally子句,我一定会执行的!")
print("程序正常退出")
def div_apple(n):
print("%d个苹果想分给几个人?" % n)
s = input("请输入人数:")
cnt = int(s) #坑你触发ValueError错误异常
#以下一行可能触发ZeroDivisionError错误异常
try
result = n / cnt
print("每个人分了",result,'个苹果')
except ZeroDivisionError:
print("被零除错误")
try:
print ("开始分苹果")
div_apple(10)
print("分苹果完成")
except:
print('错误已经被捕获')
else:
print("程序正常执行,没有异常")
finally:
print("我是finally子句,我一定会执行的!")
print("程序正常退出")
练习:
写一个函数get_score()来获取学生的成绩(0-100),如果输入出现异常,则此函数返回0,
否则返回用户输入的成绩
def get_score():
...
score = get_score()
print("学生的成绩是:",score)
实现如下:
def get_score()
s = int(input("请输入学生成绩:"))
if 0 <= s < 100:
return s
return 0
try
score = get_score()
except:
score = 0
print("学生的成绩是:",score)
def get_score()
try:
s = int(input("请输入学生成绩:"))
except:
return 0
if 0 <= s < 100:
return s
return 0
score = get_score()
print("学生的成绩是:",score)
try finally语句
语法:
try:
可能触发异常的语句
finally:
最终语句
说明:
finally子句不可以省略
一定不存在except子句
作用:
通常用try-finally语句来做触发异常时必须要处理的事情,
无论异常是否发生,finally子句都会被执行
注:
try-finally语句不会改变程序的(正常/异常)状态
示例:
以煎鸡蛋为例:
打开天燃气
煎蛋
关闭天燃气
def fry_egg():
print("打开天燃气点燃...")
count = int(input("请输入鸡蛋个数:"))
print("煎蛋完成,共煎了%d个鸡蛋" % count)
print("关闭天然气")
fry_egg()
def fry_egg():
print("打开天燃气点燃...")
try
count = int(input("请输入鸡蛋个数:"))
print("煎蛋完成,共煎了%d个鸡蛋" % count)
finally:
print("关闭天然气")
fry_egg()
def fry_egg():
print("打开天燃气点燃...")
try
count = int(input("请输入鸡蛋个数:"))
print("煎蛋完成,共煎了%d个鸡蛋" % count)
finally:
print("关闭天然气")
try:
fry_egg()
except:
print("程序已转为正常状态!")
raise语句
问题:
try - except语句干什么用?
请问错误通知谁发出的?怎么发出的?
raise语句
作用:
触发一个错误,让程序进入异常状态
语法:
raise 异常类型
或
raise 异常对象
示例1:
def make_except():
print("开始")
raise ZeroDivisionError #手动发生一个错误通知
print("结束")
try:
make_except()
print("make_except调用完毕")
except ZeroDivisionError:
print("出现了被0除的错误,已处理并转为正常状态")
def make_except():
print("开始")
e = ZeroDivisionError("被0除了")
raise e #触发e绑定的错误,进入异常状态
print("结束")
try:
make_except()
print("make_except调用完毕")
except ZeroDivisionError as err:
print("出现了被0除的错误,已处理并转为正常状态")
print('err绑定的对象是:',err)
示例2:
def get_age():
a = int(input("请输入年龄(0-140):"))
if 0 <= a <=140:
return a
if a > 140:
raise OverflowError("人的年龄不可能大于140")
try:
age = get_age()
except ValueError as err:
print("用户输入的不是数字,已经做出相应的处理")
age = 0
except OverflowError as err:
print("用户输入的年龄过大")
age = 0
print("得到的年龄是:",age)
assert语句(断言语句)
语法:
assert真值表达式,错误数据(通常是字符串)
作用:
当真值表达式为False时,用错误数据创建一个AssertionError
类型的错误,并进入异常状态
类似于:
if 真值表达式 == False:
raise AssertionError(错误数据)
示例:
def get_age():
a = int(input("请输入年龄:"))
assert 0 <= a <= 140,'年龄不在合法的范围内'
return a
try:
age = get_age()
except AssertionError as e:
print ("错误的原因是:",e)
age = 0
print("年龄是:",age)
小结
接收错误消息:
try excpet
做必须要处理的事情的语句:
try finally
发送错误消息的语句:
raise 语句
assert语句
为什么要用异常处理机制
在程序调用层数较深时,向主调函数传递错误信息需要用return语句层层传递比较麻烦,
所以用异常处理机制。
作业讲解
1、把学生管理系统划分为模块(把相关操作放在一个模块内):
建议:
main.py放主事件循环
menu.py放show_menu函数
student_info.py放学生信息相关的操作
自行调整,需要用到from xx import xx
2、模拟斗地主发牌,牌共54张,黑桃('\u2660'),梅花('\u2663'),方块('\u2665'),
红桃('\u2666')
大小王:A2 - 10JQK
三个人玩,每个人发17张牌,底牌留三张
操作:
输入回车:打印第一个人的17张牌
输入回车:打印第二个人的17张牌
输入回车:打印第三个人的17张牌
输入回车:打印三张底牌
def get_poke():
kinds = ['\u2660','\u2663','\u2665','\u2666']
number = ['A'] list(map(str,range(2,11))) list('JQK')
print(number)
L = ['大王','小王'] [x y for x in kinds for y in number]
return L
import random
def poke_games()
pk = get_poke()
random.shuffle(pk)
input("输入回车继续")
print("第一个人的17张牌是:",pk[:17])
input("输入回车继续")
print("第二个人的17张牌是:",pk[17:34])
input("输入回车继续")
print("第三个人的17张牌是:",pk[34:51])
input("输入回车继续")
print("底牌是:",pk[51:])
poke_games()
练习:
1、一个球100米高空落下,每次落下后反弹高度是原高度的一半,再落下。
(1)算出皮球在第10次落地后反弹高度是多少?
(2)打印出球共经过多少米的路程
2、分解质因数,输入一个正整数,分解质因数:
如:
输入:90
打印:
90 = 2 * 3 * 3 * 5
(质因数是指最小能被原数整数的素数(不包括1))
2019-10-30---------------day15-------------------------------------------
迭代器iterator和生成器generator
什么是迭代器
迭代器是指iter(可迭代对象)函数返回的对象(实例)
迭代器可以用next(it)函数获取可迭代对象的数据
迭代器函数:
iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是一个能提供迭代器的
可迭代对象。
net(iterable)从迭代器iterator中获取下一条记录,如果无法获取下一条记录,则触发
StopIteration异常
说明:
迭代器是访问可迭代对象的一种方式
迭代器只能向前取值,不会后退
用iter函数可以返回一个可迭代对象的迭代器
L = [1,2,3,4]
it = iter(L)
next(it)
r = range(10)
it = iter(r)
next(it)
可迭代对象 创建 迭代器 ,迭代器访问可迭代对象
问题:
能否用迭代器访问range(100,1000)中前三个数?(不用for循环语句)
r = range(100,1000)
it = iter(r)
next(it)
next(it)
next(it)
迭代器的用途:
迭代器对象能用next函数获取下一个元素
示例:
用while循环语句来访问如下列表
L = [2,3,5,7]
for x in L:
print(x)
it = iter(L)
while True:
try:
x = next(it)
print(x)
exception StopIteration:
print("迭代终止")
break
练习:
有个集合:
s = {'唐僧','悟空','八戒','沙僧'}
用for语句来打印集合内的信息:
for x in s:
print(x)
else:
print("遍历结束")
请将上面的for语句改写为while,next,iter函数组合方式实现。
it = iter(s) 先获取迭代器
while True:
try:
x = next(it)
print(x)
exception StopIteration:
print("迭代终止")
break
生成器函数
生成器Generator(python2.5及之后)
生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例)
生成器有两种:
生成器函数
生成器表达式
生成器函数定义
含有yield
语句的函数是生成器函数,此函数被调用时将返回一个生成器对象
注:yield翻译为产生(或生成)
yield语句
语法:
yield 表达式
说明:
yield用于def函数,目的是将此函数作为生成器函数使用yield用来
生成数据,供迭代器next(it)函数使用
示例:
#此示例示意生成器函数的定义及使用
def myyield():
'''此函数为生成器函数'''
yield 2 #生成2
yield 3
yield 5
#用for语句访问myyield函数
for x in myyield():
print(x)
#理解如下:
it = iter(myyield())
x = next(it)
print(x)
生成器函数说明:
生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象
在生成器函数调用return时会出生一个StopIteration异常来通知next(it)函数不再能
提供数据
练习:
1、写一个生成器函数:
def myinteger(n):
...
此生成器函数可以生产从0开始的一系列整数,到n结束(不包含n)
for x in myinteger(3):
print(x) 打印 0,1,2
it = next(myinteger(2))
print(next(it)) 0
print(next(it)) 1
print(next(it)) 2
print(next(it)) StopIteration异常
实现如下:
方法1
def myinteger(n):
i = 0
while i < n:
yield i
i =1
方法2
def myinteger(n):
for y in range(n):
yield y
for x in myinteger(3):
print(x) 打印 0,1,2
it = next(myinteger(2))
print(next(it)) 0
print(next(it)) 1
print(next(it)) 2
print(next(it)) StopIteration异常
2、写一个生成器函数mymodd(x)来生成一系列奇数
如:
myodd(10)可以生成1 3 5 7 9
def myodd(x):
i = 0
while i < x:
if i % 2 == 1:
yield i
i = 1
for x in myodd(10)
print(x)
以下两种方法的共同点和区别:
for y in myodd(3): 要一个生成一个
print(y)
for y in list(myodd(3)): 先生成列表,然后去列表取
print(y)
生成器表达式
语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
注:[]里的内容可以省略
作用:
用推导式的形式生成一个新的生成器
示例:
gen = (x**2 for x in range(1,4))
it = iter(gen)
next(it) #1
next(it) #4
next(it) #9
next(it) #16
next(it) #StopIteration
优点:
不占用内存空间
fox x in (x**2 for x in range(1,4))
fox x in [x**2 for x in range(1,4)]
列表推导式和生成表达式的区别:
L = [1,2,3,4]
gen = (x for x in L) #gen绑定生成器
lst = [x for x in L] #lst绑定列表
L[1] = 222 # 改变原列表的第二个元素
for x in lst:
print(x) # 1 2 3 4 不变
for x in gen:
print(x) # 1 222 3 4
迭代工具函数
迭代工具函数的作用是生成一个个性化的可迭代对象
函数:
zip(iter1 [,iter2,iter3,...])返回一个zip对象,此对象用于生成一个元组,此元组
的个数由最小的可迭代对象决定
emumerate(iterable[,start])
生成带索引的枚举对象,返回迭代类型为索引-值对(index,value)对,默认索引从0开始
也可以使用start绑定
示例:
numbers = [10086,10000,10010,95588]
names = ['中国移动','中国电信','中国联通']
for n,a in zip(numbers,names):
print(a,'的客服号码是:',n)
d = dict(zip(names,numbers)) 可以生成字典
for x in zip(range(10),numbers,name)
print(x)
zip函数内部实现机制
def myzip(iter1,iter2)
it1 = next(iter1)
it2 = next(iter2)
while True:
x = next(it1)
y = next(it2)
yield (x,y)
numbers = [10086,10000,10010,95588]
names = ['中国移动','中国电信','中国联通']
for x in myzip(numbers,names):
print(x)
enumerate函数(枚举函数)
emumerate(iterable[,start])
示例:
names = ['中国移动','中国电信','中国联通']
for x in enumerate(names):
print(x)
# (0,'中国移动')
index,element = x
print("索引",index,'对应的元素是:',element)
for x in enumerate(names,start=100):
print(x)
# (100,'中国移动')
练习:
写一个程序,读入任意行的文字,当输入空行时结束输入:
打印带有行号的输入结果:
如:
$ python3 mytest.py
请输入:hello<回车>
请输入:world<回车>
请输入:bye<回车>
打印如下:
第1行:hello
第2行:world
第3行:bye
实现如下:
def get_lines():
L = []
while True:
s = input("请输入:")
if not s:
break
L.append(s)
return L
def print_text(lst):
for numbers,text in enumerate(lst,start=1)
print('第',numbers,'行:',text)
if _name_ == '_main_':
print_text(get_lines())
字节串bytes 字节数组 bytearray
之前学的容器类型:
str list tuple dict set fronzenset
字节串bytes
作用:
存储以字节为单位的数据
说明:
字节串是不可变的字节序列
字节是0-255之间的整数
创建空字节串的字面值
b''
b""
b''''''
b""""""
B''
B""
B''''''
B""""""
创建非空字节串的字面值
b'ABCD'
b'\x41\x41'
b = b''
type(b)
<class 'bytes'>
字节串的构造函数bytes
bytes() 生成一个空的字节串 等同于b''
bytes(整型可迭代对象) 用可迭代对象初始化一个字节串
bytes(整数n) 生成n个值为零的字节串
bytes(字符串,encoding='utf-8')
用字节串的转换编码生成一个字节串
>>> bytes(range(97,97 26))
b'abcdefghijklmnopqrstuvwxyz'
>>> bytes('hello中国','utf-8')
b'hello\xe4\xb8\xad\xe5\x9b\xbd'
字节串的运算
= * *=
< <= > >= == !=
in / not in
索引/切片
示例:
b = b'abc' b'123' # b=b'abc123'
b = b'ABC' # b=b'abc123ABC'
>>> b'ABC' < b'ABD'
True
>>> b = b'ABC123'
>>> 65 in b
True
>>> b'A' in b
True
用于序列函数:
len(x) max(x) min(x) sum(x) all(x) any(x)
bytes与str区别(字节串与字符串的区别)
bytes存储字节(0-255)
str 存储Unicode(0-65535)
bytes与str转换
str 编码(encode) ---> bytes
b = s.encode('utf-8')
解码(dencode)
bytes 解码(dencode)---> str
s = b.decode('utf-8')
字节数组
字节数组 bytearray
可变的字节序列
list --->tuple
set --->fronzenset
bytearray--->bytes
创建字节数组的构造函数:
bytearray() 创建空的字节数组
bytearray(整数)
bytearray(整型可迭代对象)
bytearray(字符串,encoding='utf-8')
注:以上参数等同于字节串
字节数组的运算:
= * *=
< <= > >= == !=
in / not in
索引/切片(字节数组支持索引和切片赋值,规则与列表相同)
>>> ba = bytearray(b'hello')
>>> ba[::2] = [65,66,67]
>>> ba
bytearray(b'AeBlC')
>>> ba[0]
65
bytearray的方法:
B.clear() 清空字节数组
B.append(n) 追加一个字节(n为0-255的整数)
B.remove(value)删除第一个出现的字符,如果没有出现,则产生ValueError错误
B.reverse() 字节的顺序进行反转
B.decode(encoding='utf-8') #解码
B.find(sub[,start[,end]]) 查找
小结、练习讲解
小结:
迭代器
用来访问可迭代对象的数据
iter(iterable) 返回迭代器
next(iterator) 获取可迭代对象的数据
生成器函数
根据需要动态创建一些数据(数据原来不存在,用yield现用现生成)
range()
字节串和字节数组。
练习:
1、一个球100米高空落下,每次落下后反弹高度是原高度的一半,再落下。
(1)算出皮球在第10次落地后反弹高度是多少?
(2)打印出球共经过多少米的路程
实现如下:
def ball(height,times):
for _ in range(times):
height = height / 2
return height
print("球从100高度反弹10次的高度是:".ball(100,10))
def ball_distance(height,times):
s = 0
for _ in range(times):
s = height 把下落过程累加到s
height /= 2
s = height
return s*
print("球从100米的高度反弹10次后经历的路程是:",ball_distance(100,10))
2、分解质因数,输入一个正整数,分解质因数:
如:
输入:90
打印:
90 = 2 * 3 * 3 * 5
(质因数是指最小能被原数整数的素数(不包括1))
实现如下:
def is_prime(x):
if x <= 1:
return False
for i in range(2,x):
if x % i == 0:
return False
return True
def get_prime_list(n):
L = []
while not is_prme(n):
for x in range(2,n):
if is_prime(x) and n % x == 0:
L.append(x)
n /= x 下次再求n的因数
n = int(n)
break
else:
L.append(n)
return L
if _name_ == '_main_':
n = int(input("请输入整数:"))
print(get_prime_list(n))
练习:
1、用生成器函数primes(begin,end)生成素数,给出起始值begin和终止值stop,生成此
范围内的全部素数,不包含(stop)
如:
L = [x for x in primes(10,20)]
将得到列表 L = [11,13,17,19]
2、仿制range函数的功能,写一个生成器函数myrange,要求功能与range功能相近,能实现
一个,两个,三个参数传参,生成正向的整数。
如:
for x in myrange(1,10,3):
print(x) # 1,4,7
2019-11-2---------------day16-------------------------------------------
文件与操作流程
文件 file
什么是文件?
用于数据存储的单位,文件中的数据是以字节为单位顺序存储的。
文件的操作流程
打开文件
读写文件
关闭文件
任何的操作系统,一个应用程序同时打开文件的数量有最大数限制
文件的打开函数open
open(file,mode='rt')
用于打开一个文件,返回此文件对应的文件流对象,如果打开失败,则会触发OSError错误!
文件的关闭方法
F.close() 关闭,释放系统资源
示例:
try:
f = open('/etc/passwd')
print("文件打开成功!")
f.close()
except OSError:
print("打开文件失败!")
文本文件的操作
python文件读写的类型有两种:
文本文件 (text file)
二进制文件 (binary file)
文本文件的操作
默认文件中存储的都为字符数据,以行为单位进行分隔,在python
内部统一用'\n'作为换行进行分隔
对文本文件读写需要用字符串(str)进行数据读取和写入
各种操作系统的换行符:
linux: '\n'
windows: '\r\n'
旧的Macintosh: '\r'
新的Mac Os :'\n'
示例:
try:
f = open("abc.txt")
print("文件打开成功")
s = f.readline()
if s != '':
print("读取成功,文字是:",s)
else:
print("文件内已经没有数据可读取了")
s = f.readline()
print("第二行数据是:",s)
s = f.readline()
print("第三行数据是:",s)
s = f.readline()
if s == '':
print("文件内已经没有数据可读取了")
else:
print("第四行数据是:",s)
f.close()
except OSError:
print("打开文件失败")
练习:
自己写一个文件‘info.txt’内部存在一些文字信息
张三 20 100
李四 21 96
小王 22 98
写程序将这些数据读取出来,打印在屏幕终端上
实现如下:
def read_text_data():
try:
f = open("info.txt")
print("文件打开成功")
while True:
s = f.readline()
if not s:
break
if s[-1] = '\n'
print(s[:-1])
else:
print(s)
f.close()
except OSError:
print("打开文件失败")
if _name_ == '_main_':
read_text_data()
示例(readlines):
try:
f = open("../exercise/info.txt")
L = f.readlines() 读取多行
print(L)
f.close()
except OSError:
print("打开文件失败")
f.read(8) 读取多少字符
f.read()也可以读取多个
文本文件的写操作
f = open("mynote.txt",'w') 'r' 'w'清空 'a'追加
f.write("hello")
f.close()
L = ['我是第一行','我是第二行']
f.writelines(L)写入多行
f.colse()
L = ['我是第一行\n','我是第二行']
f.writelines(L)写入多行
f.colse()
练习:
1、写一个程序,从键盘输入如下信息:
姓名和电话号码
如:
请输入姓名:xiaozhang
请输入电话:138888888888
请输入姓名:xiaoli
请输入电话:139999999999
请输入姓名:<回车>
把从键盘读取的信息存入'phone_book.txt'文件中然后用
sublime text打开并查看写入的内容
实现如下:
def input_phone_number():
L = []
while True:
name = input("请输入姓名:")
if not name:
break
number = input("请输入电话:")
L.append((name,number)) #形成元组
return L
def write_to_file(lst,filename='phone_book.txt'):
try:
f = open(filename,'w')
for name,number in lst:
f.write(name)
f.write(',')
f.write(number)
f.write('\n')
f.colse()
except OSError:
print("写入文件失败")
if _name_ == '_main_':
L = input_phone_number()
print(L)
2、写一个读取'phone_book.txt'文件的程序,把保存的信息以表格的形式打印出来。
---------------- --------------
| name | number |
---------------- --------------
| xiaozhang | 138888888 |
---------------- --------------
实现如下:
def read_info_from_file(filename = 'phone_book.txt'):
L = []
try:
f = open(filename)
while True:
s = f.readline()
if not s:
break
s = s.rstrip() 去掉右侧的换行符'\n'
name,number = s.split(',')
L.append((name,muber))
f.close()
except OSError:
print("打开文件失败!")
return L
def print_infos(lst):
print("打印表格自己实现")
print(lst)
if _name_ == '_main_':
L = read_info_from_file()
print_infos(L)
文件迭代读取、标准输入输出
文本文件的迭代读取
open()函数返回来的文件对象是可迭代对象
示例:
f = open('abc.txt')
for line in f: #相当于line = f.readline()
print(line)
f.close()
标准输入输出文件
模块名:sys
sys.stdin(默认为标准键盘输入设备)
ctrl d 输入文件末尾标识
sys.stdout(默认为屏幕终端)
sys.stderr(默认为屏幕终端)
标准文件不需要打开和关闭就可以使用
示例:
import sys
s = sys.stdin.readline()
print("从键盘读取的第一行是:",s)
s = sys.stdin.read()
print("read读取的信息是:",s)
print("程序退出")
import sys
sys.stdout.write("hello world\n")
sys.stderr.write("我的出现是个错误")
flush方法
示例:
import time
f = open("info.txt",'w')
f.write("hello")
print("开始睡觉") #没有写到磁盘
time.sleep(15)
print("我醒了") #写到磁盘了
f.close()
import time
f = open("info.txt",'w')
f.write("hello")
f.flush() 强制清空缓冲区
print("开始睡觉")
time.sleep(15)
print("我醒了")
f.close()
二进制文件操作
'b' 二进制(binary)文件操作
对于二进制文件的读写通常需要用字节串(bytes)进行操作
示例:
f = open("infos.txt",'rb') #以二进制模式打开
f.close()
#读取二进制文件内容,然后转为字符串
try:
f = open("infos.txt",'rb')
b = f.read(5) #代表5个字节
print(b)
b = f.read(2)
print(b)
b = f.read() 读取全部字节,直至文件尾
print(b)
print("读取的内容转为文字后为:",b.decode('utf-8'))
f.close()
except OSError:
print("打开文件失败")
#以二进制的模式进行写操作
try:
f = open("infos.txt",'wb')
f.write(b'\xe4')
f.write(b'\xb8')
f.write(b'\xad')
print(b)
f.close()
except OSError:
print("文件打开失败")
f.tell() 返回当前文件流的绝对位置
f = open('data.txt','rb')
print("当前的读写位置是:",f.tell()) #0
b = f.read(5)
print("当前的读写位置是:",f.tell()) #5
b = f.read()
print("文件最后的位置是:",f.tell()) #20 最多就是20
f.close()
f.seek(offset,whence=0)改变数据流的位置,返回新的绝对位置
f.seek(偏移量,whence=相对位置)
偏移量:
大于0代表向文件末尾方向移动
小于0代表向文件头方向移动
相对位置:
0 代表从文件头开始
1 代表从当前读写位置开始偏移
2 代表从文件尾开始偏移
示例:
f = open('data.txt','rb')
f.seek(5,0) 相对于文件头向后移动5个字节
b = f.read(5)
print(b)
f.close()
f.seek(-15,2) 从文件尾开始偏移
b = f.read(2)
f.seek(3,1)从当前读写位置开始偏移
汉字、python编码
问题:
10个汉子占多少字节?
gbk:20个字节 utf-8:30个字节
汉字编码:
国标系列:
GB18030(二字节或四字节编码)
GBK(二字节编码)
GB2312(二字节编码) 1980年收入,六千多个字符
(windows常用)
国际标准:
Unicode <---> UTF-8
(linux/mac os/ios/android常用)
python3:Unicode16/32 二字节/四字节编码
python编码(encode)字符串
'gb2312'
'gbk'
'gb18030'
'utf-8'
'assii'
...以下略
s = '中文'
s.encode('utf-8')
s.encode('gb18030')
编码注释:
在源文件的第一行或第二行写入如下内容为编码注释
# -*- coding:gbk -*-
#设置源文件编码为:gbk
或
# -*- coding:utf-8 -*-
# 设置源文件编码为:utf-8
练习:
1、写程序让用户输入一系列整数,当输入小于零的数时结束输入
将输入的数字存在于列表中,将列表中的数字写入到文件numbers.txt中
(提示:需要整数转为字符串或字节串才能存入文件中)
2、写程序,将文件numbers.txt中的整数读入到内存中,重新形成数字组成的
列表,计算这些数的最大值、最小值和他们的和。
3、为学生信息管理项目添加两个功能:
9)保存信息到文件(si.txt)
10)从文件中读取数据(si.txt)
(建议以行为单位存储数据,用空格或逗号作为姓名,年龄和成绩的分隔符)
2019-11-3----面向对象------------------------------------
面向对象和类
object(对象)
什么是对象
对象是指现实中的物体或实体
什么是面向对象
把一切看成对象(实例),让对象和对象之间建立关联关系
对象都有什么特征
对象有很多属性(名词)
姓名,年龄,性别
对象有很多行为(动作,动词)
学习,吃饭,睡觉,踢球,工作
什么是类:class
拥有相同属性和行为的对象分为一组,即为一类
类是用来描述对象的工具,用类可以创建同类对象
车(类)
狗(类)
int(类) ---->100(对象/实例)
\
\----->200 (对象/实例)
类的创建
语法:
class 类名(继承列表):
'''类的文档字符串'''
实例方法定义(类内的函数称为方法method)
类变量定义
类方法定义
静态方法定义
作用:
创建一个类
用于描述此类对象的行为和属性
类用于创建此类的一个或多个对象(实例)
示例:
class Dog:
pass
dog1 = Dog() #创建Dog类的对象
dog2 = Dog() #创建Dog类的另一个对象
类和对象
类 对象 实例
class object instance
实例方法和属性
构造函数:
表达式:
类名([创建传参列表])
作用:
创建这个类的实例对象,并返回此实例对象的引用关系
实例(对象)说明
实例有自己的作用域和名字空间,可以为该实例添加实例变量(属性)
实例可以调用类方法和实例方法
实例可以访问类变量和实例变量
class Dog:
pass
dog1 = Dog()
实例方法:
语法:
class 类名(继承列表):
def 实例方法名(self,参数1,参数2,...):
'''实例方法的文档字符串'''
语句块
作用:
用于描述一个对象的行为,让此类型的全部对象拥有相同的行为。
说明:
实例方法实质是函数,是定义在类内的函数
实例方法至少有一个形参,第一个形参代表调用这个方法的实例,一般命名为'self'
实例方法的调用语法:
实例.实例方法名(调用传参)
或
类名.实例方法名(实例,调用传参)
示例:
class Dog:
def eat(self,food):
print("小狗正在吃:",food)
def sleep(self,hour):
print("小狗睡了",hour,"小时")
def play(self,obj):
print("小狗正在玩",obj)
dog1 = Dog() 创建一个Dog的类的实例
dog1.eat('狗粮')
dog1.sleep(1)
dog1.play("球")
Dog.play(dog1,'杂技')
实例属性
attribute(也叫实例变量)
每个实例都可以有自己的变量,此变量称为实例变量(也叫属性)
属性的使用语法:
实例.属性名
赋值规则:
首次为属性赋值则创建此属性
再次为属性赋值则必变属性的绑定关系
作用:
用来记录对象自身的数据
示例:
class Dog:
pass
dog1 = Dog()
dog1.kinds = '京巴'
dog1.color = '白色'
dog1.color = '黄色' 改变属性的绑定关系
print(dog1.color,'的',dog1.kinds) 访问属性 # 黄色的京巴
dog2 = Dog()
dog2.kinds = '牧羊犬'
dog2.color = '灰色'
print(dog2.color,'的',dog2.kinds) 访问属性
实例方法和实例变量(属性)结合在一起使用
class Dog:
def eat(self,food):
print(self.color,'的',self.kinds,'正在吃',food)
dog1 = Dog()
dog1.kinds = '京巴'
dog1.color = '白色'
dog1.eat("骨头")
练习:
定义一个学生类
class Student:
def set_info(self,name,age):
'''此方法用来给学生对象添加'姓名'和'年龄'属性
def show_info(self):
'''此处显示此学生的信息'''
如:
s1 = Student()
s1.set_info('小张',20)
s2 = Student()
s2.set_info('小李',18)
s1.show_info() #小张今年20岁
s2.show_info() #小李今年18岁
实现如下:
class Student:
def set_info(self,name,age=0):
self.name = name
self.age = age
def show_info(self):
print(self.name,'今年',self.age,'岁')
s1 = Student()
s1.set_info('小张',20)
s2 = Student()
s2.set_info('小李',18)
s1.show_info() #小张今年20岁
s2.show_info() #小李今年18岁
删除属性及初始化方法
用del语句可以删除一个对象的实例变量
语法:
del 对象.实例变量名
示例:
class Cat:
pass
c1 = Cat()
c1.color = "白色" #添加属性
print(c1.color)
del c1.color #删除属性
print(c1.color) #属性错误
初始化方法:
作用:
对新创建的对象添加实例变量(属性)或相应的资源。
语法格式:
class 类名(继承列表):
def _init_(self,[,形参列表]):
语句块
说明:
1、初始化方法名必须为_init_不可改变
2、初始化方法会在构造函数创建实例后自动调用,且次实例自身通过第一个参数
self传入_init_方法
3、构造函数的实参将通过_init_方法的形参列表传入_init_方法中
4、初始化方法内部如果需要返回则只能返回None
示例:
class Car:
def _init_(self,c,b,m):
print("_init_方法被调用")
self.color = c #颜色
self.brand = b #品牌
self.model = m #型号
def run(self,speed):
print(self.color,'的',self.brand,self.model,'正在以',speed,'公里/小时的速度行驶!')
a4 = Car('红色','奥迪','A4')
# a4.color = '黑色' 或如下
a4.set_color('黑色')
a4.run(179)
练习:
修改之前Student类:
(1)为该类增加初始化方法,实现在创建对象时自动设置“姓名”,“年龄”,“成绩”属性
(2)添加set_score方法能为对象修改成绩信息
(3)添加show_info方法打印学生对象的信息
实现如下:
class Student:
def _init_(self,name,age=0,score=0):
self.name = name
self.age = age
self.score = score
def show_info(self):
print(self.name,'今年',self.age,'岁','成绩是:',self.score)
def set_score(self,s)
self.score = s
s1 = Student()
s1.set_info('小张',20)
s2 = Student()
s2.set_info('小李',18,100)
s1.show_info() #小张今年20岁
s2.show_info() #小李今年18岁
s1.set_score(97)
析构方法
语法:
class 类名(集成列表):
def _del_(self):
语句块
说明:
析构方法在对象销毁时被自动调用
作用:
清理此对象所占用的资源
Python不建议在析构方法内做任何事情,因为对象销毁的时间难以确定
示例:
class Car:
def _init_(self,name):
self.name = name
print('汽车',name,'对象已经创建')
def _del_(self):
print(self.name,'对象已经销毁')
c1 = Car('BYD E6')
while True: #死循环阻止程序退出
pass
预置实例二属性
_dict_属性
此属性绑定一个存储此实例自身变量的字典
示例:
class Dog:
pass
dog1 = Dog()
print (dog1._dict_)
dog1.kinds = '京巴'
print(dog1._dict_)
_class_属性
此属性用来绑定创建此实例的类
作用:
可以借助此属性来访问创建此实例的类
示例:
class Dog:
pass
dog1 = Dog()
dog2 = Dog()
dog3 = dog1._class_()
dog1._class_ is Dog # True
面向对象的综合示例
有两个人:
1、姓名:张三
年龄:35
2、姓名:李四
年龄:8
行为:
1、教别人学东西teach
2、赚钱
3、借钱
事情:
张三教李四学python
李四教张三学跳皮筋
张三上班赚了1000元钱
李四向张三借了200元钱
示例:
class Human:
'''人类,用于描述人的行为和属性'''
def _init_(self,n,a):
self.name = n
self.age = a
self.money = 0
def teach(self,other,skill):
print(self.name,'教',other.name,'学',skill)
def works(self,money):
self.money = money
print(self.name,'工作赚了',money,'元钱')
def borrow(self,other,money):
if other.money > money:
print(other.name,'借给',self.name,money,'元钱')
other.money -= money
self.money = money
else:
print(other.name,'不借给',self.name)
def show_info(self):
print(self.age,'岁',self.name,'存有',self.money,'元钱')
#以下是类的使用
zhangsan = Human('张三',35)
lisi = Human('李四',8)
zhangsan.teach(lisi,'python')
lisi.teach(zhangsan,'跳皮筋')
zhangsan.works(1000)
lisi.borrow(zhangsan,200)
zhangsan.show_info()
lisi.show_info()
用于类的函数:
isinstance(obj,class_or_tuple)返回这个对象obj是否某个类class或某些类的实例,如果是
则返回True,否则返回False
type(obj) 返回对象的类型
示例:
class Dog:
pass
class Cat:
pass
animal = Dog()
isinstance(animal,Dog) #True
isinstance(animal,Cat) #False
isinstance(animal,(Cat,int,list)) #False
isinstance(animal,(Cat,int,Dog)) #True
type(animal) 等同于 animal._class_
作业讲解
练习:
1、用生成器函数primes(begin,end)生成素数,给出起始值begin和终止值stop,生成此
范围内的全部素数,不包含(stop)
如:
L = [x for x in primes(10,20)]
将得到列表 L = [11,13,17,19]
实现方法:
def is_prime(x):
if x <= 2:
return False
for i in range(2,x):
if x % i == 0:
return False
return True
def primes(begin,end):
i = begin
while i < end:
if is_prime(i):
yield i
i = 1
L = [x for x in primes(10,20)]
print(L)
2、仿制range函数的功能,写一个生成器函数myrange,要求功能与range功能相近,能实现
一个,两个,三个参数传参,生成正向的整数。
如:
for x in myrange(1,10,3):
print(x) # 1,4,7
实现方法:
def myrange(start,stop=None,step=1):
if stop is None:
stop = start
start = 0
i = start
while i < stop:
yield i
i = step 增加i的值,供下次使用
print(list(myrange(5)))
print(list(myrange(10,15)))
for x in myrange(1,10,3):
print(x)
练习:
1、写程序让用户输入一系列整数,当输入小于零的数时结束输入
将输入的数字存在于列表中,将列表中的数字写入到文件numbers.txt中
(提示:需要整数转为字符串或字节串才能存入文件中)
实现如下:
def get_number():
L = []
while True:
i = int(input("请输入整数:"))
if i < 0:
break
L.append(i)
return L
def save_to_file(lst,filename='numbers.txt')
try:
f = open(filename,'w')
for i in lst:
f.write(str(i))
f.write('\n')
f.close()
except OSError:
print("打开文件失败")
if _name_ == '_main_':
L = get_number()
print(L)
save_to_file(L)
2、写程序,将文件numbers.txt中的整数读入到内存中,重新形成数字组成的
列表,计算这些数的最大值、最小值和他们的和。
实现如下:
def read_from_file(filename='numbers.txt')
try:
f.open(filename)
try:
for line in f:
n = int(line.rstrip())
L.append(n)
finally:
f.close()
except OSError:
print("读取文件出错")
except ValueError:
print("读取文件时出错,数据可能不完整")
return L
if _name_ == '_main_':
L = read_from_file()
print("最大:",max(L))
print("最小:",min(L))
print("和是:",sum(L))
3、为学生信息管理项目添加两个功能:
9)保存信息到文件(si.txt)
10)从文件中读取数据(si.txt)
(建议以行为单位存储数据,用空格或逗号作为姓名,年龄和成绩的分隔符)
4、修改之前的学生管理系统
原学生数据使用字典存储,现改为用对象存储,要求自定义Student类来封装
学生的信息和行为
file:student.py
class Student:
def _init_(self,n,a,s):
self.name = n
...
from student import Student