集合
列表,字典是以后我们写代码最常使用的数据类型
而集合却是一用上就发现了新大陆一样
特性:去重,关系测试
1 list_1 = set([1,3,5,7,8,6,9]) 2 list_2 = set([2,4,6,8,10]) 3 print(list_1,list_2) 4 list_3 = set( [1,2,3,4] ) 5 list_4 = set ( [3,4] ) 6 print( 1 in list_4 ) 7 print( 3 not in list_3) 8 9 # discard 与 remove的区别就是 dicard删除不存在的元素不会报错但是remove会 10 # list_3.discard(5) 11 # list_4.remove(5) 12 # print(list_3) 13 14 # 判断list_3是不是list_4的父集 15 # print(list_3.issuperset(list_4)) 16 17 # list_3.update([3,4,5,6,7,8]) 18 # print(list_3) 19 # list_3.update('hello') 20 # list_3.remove(1) 21 # print(list_3) 22 23 # 如果2个集合的交集为None,返回True 24 # print( list_3.isdisjoint(list_4) ) 25 26 #随机删除 27 # list_1.pop() 28 # print(list_1) 29 # 清除里面的数据,剩下一个空集合 30 # list_1.clear() 31 # print(list_1) 32 # 添加元素 33 # list_1.add(8888) 34 # print(list_1) 35 36 37 # 交集 38 # print(list_1.intersection(list_2)) 39 # print(list_2 & list_1) 40 41 # 合集 42 # print(list_1.union(list_2)) 43 # print(list_2 | list_1) 44 45 # 差集 list_1 - 交集 in list_1 but not in list_2 46 # print(list_1.difference(list_2)) 47 # print(list_1 - list_2) 48 49 # 对称差集 合集-交集 50 # print(list_1.symmetric_difference(list_2)) 51 # print(list_2 ^ list_1)
文件操作
读:
1 # 读 2 3 # high 4 # 这里的f就是迭代器,只在内存中保留当前行 5 # f = open("yesterday","r",encoding="utf-8") 6 # count = 0 7 # for i in f: 8 # if count == 10: 9 # print("-------------") 10 # count += 1 11 # continue 12 # print(i) 13 # count += 1 14 15 # low 16 # readlines将每行转换成list里面的元素 17 # readline是一行行的读 18 19 # f = open("yesterday","r",encoding="utf-8") 20 # for index,i in enumerate( f.readlines() ): 21 # if index ==10 : 22 # print("-------------------------") 23 # continue 24 # print(i) 25 26 27 # encoding,一定要写上,默认打开的window的文件是gbk编码,而Python是unicode,utf-8的编码 28 # Python是不认识gbk编码 29 # f是文件句柄:包含文件名,文件大小,字符集,文件在硬盘上的起始位置 30 # read是读取文件所有 31 32 # f = open("yesterday","r",encoding="utf-8") 33 # data = f.read() 34 # print(data) 35 36 # 打开文件,读取文件内容 37 # data = open("yesterday",encoding="utf-8").read() 38 # print(data)
备注:
第一种以迭代器方式的读效率最高。
F既可以称为文件句柄,也是可以称为一个文件内存对象,我们对硬盘上的文件的操作都是通过文件对象进行操作的。所以我们要对他贴标签,才可以在内存中找到这个文件的对象然后对其进行操作,与变量名一样的。
window的编码都是gbk,但是python的编码是unicode的utf-8,utf-8不认识gbk,所以我们在打开文件的时候一定要指定用什么编码打开。
文件很笨,当你用r模式打开文件,那么这个文件也就只能读
写:
w:写模式,重新创建一个文件,如果原本存在这个文件,就覆盖原来的文件,不存在就会重新创建一个。
以读模式打开文件,就只能读,不能修改。
1 f = open("yesterday","w",encoding="utf-8") 2 f.write("hello,nihao !")
追加
a:以追加的模式打开文件,写内容只能追加到文件的末尾,不可读
1 f = open("yesterday","a",encoding="utf-8") 2 f.write("---------------------------->>>>>>>>>>>>>")
其他方法
1 f = open("yesterday","r",encoding="utf-8") 2 print(f.isatty())# 判断是不是个终端设备文件,打印机,驱动 3 print(f.seekable())# 判断文件指针是不是可以移动,设备文件不可以移动 4 print(f.encoding)# 输出打开的文件的编码 5 print(f.fileno())#这个是文件句柄在内存中的编号。 6 7 8 9 # f = open("yesterday","w",encoding="utf-8") 10 # f.write("-----1-------alex--------------1") 11 # f.write("-----2-------alex--------------1") 12 # f.write("-----3-------alex--------------1") 13 # f.write("-----4-------alex--------------1") 14 # print(f.tell()) 15 # f.seek(5) 16 # f.truncate( 10 )#不管你将文件指针指向哪儿,都是都是从文件的开头截断 17 18 19 # f = open("yesterday","r",encoding="utf-8") 20 # print( f.tell() )#得到文件指针 21 # f.seek(10)#移动文件指针 22 # print(f.readline()) 23 24 # f = open("yesterday","r",encoding="utf-8") 25 # print(f.name)#打印文件的名字
flush:刷新
当你写文档时,你写一句话,你以为是写到了硬盘中,但是其实不是,因为大家都知道硬盘的读写速度是很慢的,所以不可能写一句,就往硬盘里面读一句,所以它是有缓存区的,到达阈值,它再一同往硬盘里面刷。这样有可能一旦断电就没有了,所以,我假设有个新需求,就是需要写一句就往硬盘上强制刷新一句。
buffer:这个是缓冲区,很小,大概几十K而已
1 import sys,time 2 for i in range(20): 3 sys.stdout.write("#") 4 sys.stdout.flush() 5 time.sleep(0.1)
1 # f = open("yesterday","r+",encoding="utf-8")#读写,可读,以追加写,先读,后写 2 # print(f.readline()) 3 # f.write("----------------------->>woaini") 4 5 # f = open("yesterday","w+",encoding="utf-8")写读,先写,后读 6 # f.write("--------------------hehe1---------------------\n") 7 # f.write("--------------------hehe2---------------------\n") 8 # f.write("--------------------hehe3---------------------\n") 9 # f.write("--------------------hehe4---------------------\n") 10 # f.write("--------------------hehe5---------------------\n") 11 # print(f.tell()) 12 # print(f.readline()) 13 # print(f.readline()) 14 # print(f.readline()) 15 # f.seek(10) 16 # print(f.readline()) 17 # f.write("我爱北京天安门") 18 # print(f.tell()) 19 # print(f.readline()) 20 21 f = open("yesterday","a+",encoding="utf-8")先追加写,后读 22 print(f.tell()) 23 f.write("\n笑话---------------\n") 24 print(f.tell()) 25 f.seek(0) 26 print(f.readline())
f = open("yesterday","rb") print(f.readline()) print(f.readline()) print(f.readline())
rb:与读的方打开二进制文件。音视频是二进制文件,网络传输的数据是二进制的字节数据类型。
f = open("yesterday","wb") f.write("我爱北京天安门".encode())
写一个二进制文件,字符串要encode。
修改文件有2种方式:
第一;linux上面,用vim的方式将文件加载到内存里面,进行修改,是可以往后面挤的,最后再写入到硬盘里面去。
第二:硬盘上面修改,但是是覆盖原来的内容。
但是,我们将2个G的文件用vim在Linux内存中加载出来,再进行修改实在是太慢,而且占用内存,所以我们如何修改文件?
1 f = open("yesterday","r",encoding="utf-8") 2 f_new = open("yesterday2","w",encoding="utf-8") 3 for line in f: 4 if "多肆意的快乐等我享受" in line: 5 line = line.replace("多肆意的快乐等我享受","多肆意的快乐等ALEX享受") 6 7 f_new.write(line) 8 f.close() 9 f_new.close()
字符编码
等我自己屡清楚
函数
三种编程方式: 1.面向对象:华山派-----》类---》class 2.面向过程:少林派-----》过程---》def 3.函数式编程:逍遥派----》函数---》def
什么叫面向过程的程序设计方法: 把你一段的功能或者逻辑,包含在def定义的过程当中,想用的时候,用函数名(过程名)加小括号
面向过程,就是将你的代码的一段段功能或者逻辑用def块里面,链接起来。
#Author:DongWenJuan #函数 def func1(): """testing1""" print("in the func1") return 0 #过程 def func2(): """testing2""" print("in the func2") #过程其实就是没有返回值的函数,在python中没有太大的界限,python会隐式的给过程返回一个None值 x=func1() y=func2() print("form func1 return %s"%x) print("form func1 return %s"%y)
1 import time
2 def logger():
3 time_format = '%Y-%m-%d %X'
4 time_current = time.strftime(time_format)
5 with open("a.txt","a") as f:
6 f.write("%s en section"%time_current)
7 def test1():
8 print("in the test1")
9 logger()
10 def test2():
11 print("in the test2")
12 logger()
13
14 def test3():
15 print("in the test3")
16 logger()
17 test1()
18 test2()
19 test3()
函数的优点:
1.代码的重用
2.代码的一致性
3.代码的可扩展性
返回值 return
1 def test1():
2 print("in the test1")
3
4 def test2():
5 print("in the test1")
6 return 0
7
8 def test3():
9 print("in the test1")
10 return 1,[1,2,3],(4,5,6),{'name':'alex','age':12}
11 x = test1()
12 y = test2()
13 z = test3()
14 print(x,y,z)
执行结果
in the test1 in the test1 in the test1 None 0 (1, [1, 2, 3], (4, 5, 6), {'name': 'alex', 'age': 12})
返回值个数 =0 是 结果为 None
返回值个数 =1 是 结果为 Object
返回值个数 >1 是 结果为 tuple
return的作用:
1.返回函数的return值
2.结束函数
1 def test2(): 2 print("in the test1") 3 return 0 4 print("hello world") 5 test2()
6 打印结果 7 in the test1
大家可以看到上面的hello world并没有打印出来,return就是结束整个函数。
函数的形式参数
1.位置参数
2.关键字参数
3.默认参数
4.参数组
1 # 位置参数与实参一定要一一对应不可多,不可少
2 def test1(x,y):
3 print(x)
4 print(y)
5 test1(1,2)
6 # 关键字参数与形参的顺序无关
7 def test2(x,y):
8 print(x)
9 print(y)
10 test2(x=3,y=2)
11 # 位置参数与关键字参数混用,但是记住,关键字参数永远要放在位置参数的后面
12 def test3(x,y):
13 print(x)
14 print(y)
15 test3(2,y=3)
形参,形式上的参数,并不真实存在,并不占用咱们的内存空间,只有在调用函数的时候,才占用空间
实参,实际在内存中占用空间的参数,真实存在。
1 # 默认参数,可传可不传,这里大家可以理解为python隐式的传了一个关键字参数 2 def test1(name,age=18): 3 print(name,age) 4 test1('alex')
def test1(name,age=18):
print(name,age)
test1('alex')
test1('aaaa',3)
test1('bbbbb',age=44)
默认参数有2种传参方式:1.位置参数传参;2.关键字参数传参
1 # *代表args具有某功能,args是变量名 2 # 把n个位置参数,转换为元组的方式 3 # def test1(*args): 4 # print(args) 5 # test1(1,2,3,4,5) 6 # test1(*[6,7,8,9,10]) 7 8 # def test2(x,*args): 9 # print(x) 10 # print(args) 11 # test2(1,2,3,4,5)
def test3(x,*args,y=3): print(x) print(y) print(args) test3(1,5,6,7,8,10) 运行结果: 1 3 (5, 6, 7, 8, 10) def test3(x,*args,y=3): print(x) print(y) print(args) test3(1,5,6,7,8,10,y=10) 运行结果: 1 10 (5, 6, 7, 8, 10) def test4(x,y=3,*args): print(x) print(y) print(args) test4(1,2,3,4,5,6) 运行结果 1 2 (3, 4, 5, 6)
1 # **kwargs 把n个关键字参数,转换为字典的方式 2 # def test1(**kwargs): 3 # print(kwargs) 4 # test1(name="alex",age=19) 5 test1(**{'name':'alex','age':18}) 6 # def test2(name,**kwargs): 7 # print(name) 8 # print(kwargs) 9 # test2("alex",age=18,hobby='girl')
1 def test3(name,age=18,**kwargs): 2 print(name) 3 print(age) 4 print(kwargs) 5 test3("alex",age=19,sex='m',hobby="girl") 6 test3("alex",sex='m',hobby="girl",age=19)
1 def test1(name,*args,**kwargs): 2 print(name) 3 print(args) 4 print(kwargs) 5 test1("alex",age=18) 6 当没有给args传值是,默认是空元组 7 结果为 8 9 alex 10 () 11 {'age': 18}
1 def test1(name,age=19,*args,**kwargs): 2 print(name) 3 print(age) 4 print(args) 5 print(kwargs) 6 test1("alex",18,6,7,8) 7 8 结果为 9当没有给kwargs传值时,默认是空字典
10 alex 11 18 12 (6, 7, 8) 13 {}
1 def test1(name,age=19,*args,**kwargs): 2 print(name) 3 print(age) 4 print(args) 5 print(kwargs) 6 # test1("alex",age=18,6,7,8,sex="m",hobby="tesla") 报错,记住位置参数永远要在关键字参数前面 7 # test1("alex",18,6,7,8,sex="m",hobby="tesla",age=99) 报错,age赋值给了多个值,前面给age赋值18,后面又赋值99 8 test1("alex",18,6,7,8,sex="m",hobby="tesla")
作用域,局部和全局变量
school = 'oldboy'
def change_name(name):
global school
school = 'Mage'
print("before name",name,school)
name = "Alex Li"
print("after name", name)
age = 23
name = "alex"
change_name(name)
print(name)
print(school)
print(age)#报错
全局变量:
全局变量的作用范围是整个程序;
定义一个全局变量是在函数的顶层定义,注意这个顶层并不是文件头,而是程序的第一层,可以在函数的任何一个地方调用。
局部变量:
局部变量不可修改全局变量
局部变量只在子函数里面生效,它的作用域只是在子函数里面,出了函数就被释放。
如果非要在函数里面修改全局变量,就用global关键字
全局变量与局部变量重名时:局部变量在子函数中生效,其他地方是全局变量生效。
1 def change_name(): 2 global name 3 name = "alex" 4 change_name() 5 print(name)
请不要这样用,用完就被开除,因为,任何的全局变量都应该在程序的顶层显示的定义。
1 name = ["alex","jack"] 2 def change_name(): 3 name[0] = "ALEX" 4 5 print(name) 6 change_name() 7 print(name) 8 9 运行结果 10 11 ['alex', 'jack'] 12 ['ALEX', 'jack']
上面说过,局部变量改变不了全局变量
但是是针对:字符串,整数,局部变量改变不了全局的变量
但是列表,字典,集合,包括后面的类,是可以改变的。
递归
特点:
1.必须要有明确的结束条件。不然就成死循环。
2.每一次递归的问题规模要比上一次有所减少。栈
3.递归的效率是不高的。
def cala(n): print(n) if int(n/2)>0: return cala( int(n/2) ) print("hehehe") cala(10)
函数式编程和我们所写的函数是不一样的。
高阶函数:
把一个函数当作参数传给宁外一个函数
def test(x,y,f): return f(x)+f(y) res = test(1,-10,abs) print(res)