实例介绍
下载后,请改成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
好例子网口号:伸出你的我的手 — 分享!
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)
支持(0) 盖楼(回复)