在好例子网,分享、交流、成长!
您当前所在位置:首页Python 开发实例Python语言基础 → python学习笔记--达内

python学习笔记--达内

Python语言基础

下载此实例
  • 开发语言:Python
  • 实例大小:2.77M
  • 下载次数:62
  • 浏览次数:711
  • 发布时间:2020-07-11
  • 实例类别:Python语言基础
  • 发 布 人:zhouweichild
  • 文件格式:.docx
  • 所需积分:2
 相关标签: python py 笔记 学习

实例介绍

下载后,请改成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
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
		
		
		































































标签: python py 笔记 学习

实例下载地址

python学习笔记--达内

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 husw 发表于: 2020-07-13 12:09 52
我来说两句...

支持(0) 盖楼(回复)

第 2 楼 husw 发表于: 2020-07-13 12:10 11
差评

支持(0) 盖楼(回复)

第 3 楼 zhouweichild 发表于: 2020-07-13 13:02 13
差评

husw 2020-07-13 12:10 11

这个的确是有问题,弄错了,你下载word版本,绝对的学习笔记!

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有3条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警