WEEK3:函数、递归、内置函数
- 集合
list_1=[1,4,5,7,3,6,7,9]
list_2=[2,6,0,66,22,8,4]- 去重 list_1=set(list_1) #type为集合
- 关系测试
- 交集
list_1=set(list_1)
list_2=set(list_2)
print(list_1.intersection(list_2)) 或者 print(list_1 & list_2) - 并集
list_1=set(list_1)
list_2=set(list_2)
print(list_1.union(list_2)) 或者 print( list_1 | list_2) - 差集
list_1=set(list_1)
list_2=set(list_2)
print(list_1.difference(list_2)) 或者 print(list_1 - list_2) - 子集
list_1=set(list_1)
list_2=set(list_2)
print(list_1.issubset(list_2)) #判断1是否为2的子集
print(list_1.issuperset(list_2)) #判断1是否为2的父集 - 对称差集
print(list_1.symmetric_difference(list_2)) 或者 print( list_1 ^ list_2) #并集中去掉交集 - 检查是否存在交集
print(list_2.isdisjoint(list_1)) #没有为True,否则为False
- 交集
- 修改
- 添加 list_1.add(999) 或者 list_1.update([111,222,333])
- 删除 list_1.remove(1) 或者 list_1.discard(1) #安全删除,discard不会报错
- 文件操作
- 打开文件
- f=open("yesterday") #文件句柄
- with open("yesterday",'r') as f , open("yesterday2",'r') as f2: #及时关闭文件,回收内存
......
- 修改
- 方式一
将文件全部加载到内存中,然后再修改,类似vim #大文件时需要大内存 - 方式二
逐行读取,修改后写入新文件
#修改含有“肆意的快乐”的行
f=open("yesterday2",'r')
f_new=open("yesterday2.bak",'w')
for line in f:
if “肆意的快乐” in line:
line=line.replace("肆意的快乐","siyidekuaile")
f_new.write(line)
- 方式一
- 读取
- 全部读取
f=open("yesterday",'r')
data=f.read() - 读取一行
data=f.readline() - 按行读成列表
data=f.readlines() - 每次只读一行进内存,且内存中只保存一行
for line in f:
print(line)
- 全部读取
- 写入
f=open("yesterday",'w')
f.write("我爱北京天安门") - 追加
f=open("yesterday",'a')
f.write("我爱北京天安门") - 打开文件之后,指针位置
f=open("yesterday",'a')
print(f.tell()) - 读取、修改指针位置
f.tell() f.seek(0) #将指针回到文件开始 - 打印文件编码
print(f.encoding) - 内存中的文件操作写入到文件上
f.flush() - 截断文件
f=open("yesterday",'a')
f.truncate(10) #从文件头开始截取,移动指针函数失效 - 以读追加方式打开文件
f=open("yesterday","r+") - 以写追加的方式打开文件
f=open("yesterday","w+") - 以追加读的方式打开文件
f=open("yesterday","a+") - 读取二进制文件
f=open("yesterday",'rb') #网络传输时经常用到 - 写二进制文件
f=open("yesterday",'wb')
f.write("hello binary\n".encode())
f.close()
- 打开文件
- 字符编码与转码
- GBK转成UTF-8
首先通过编码decode("GBK")转换成Unicode,然后通过解码encode("UTF-8")转换成UTF-8 - UTF-8转成GBK
首先通过编码decode("UTF-8")转换成Unicode,然后通过解码encode("GBK")转换成GBK
- GBK转成UTF-8
- 函数与函数式编程
- 编程方法
- 面向对象:类,class
- 面向过程:过程,def,不需要return(即没有返回值的函数)
- 函数式编程:函数,def,必须有return
1 python中函数的定义方法: 2 3 def test(x): 4 "The function definitions" 5 x+=1 6 return x 7 8 #def:定义函数的关键字 9 #test:函数名 10 #():内可定义形参 11 #"..":文档描述(非必要,但是强烈建议为你的函数添加描述信息) 12 #x+=1:泛指代码块或程序处理逻辑 13 #return:定义返回值
- 参数
- 形参和实参
- 形参:形式参数,不是实际存在的,是虚拟变量,在定义函数和函数体的时候使用形参,目的是在函数调用时接受实参(形参个数和类型应与实参一一对应)
- 实参:实际参数,调用函数时传给函数的参数,可以是常量、变量、表达式、函数、
#区别:形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元。实参是一个变量,占用内存空间。数据传送单向,只能实参传给形参。
- 位置参数和关键字:
def test(x,y):
- 位置参数调用:test(1,2),x对应1,y对应2,既不能多也不能少
- 关键字调用:test(y=2,x=1)
- 混合调用:test(1,y=2) #先位置参数调用,然后再关键字调用,并且关键字参数不能写在位置参数前面,例如test(1,x=2)会报错,y没有赋值
- 默认参数
def test(x,y=2): #y如果不赋值,则默认为2
- 特点:调用函数的时候,默认参数可有可无
- 参数组
参数组的接收参数个数为0到无穷,且参数组只能放在默认参数和形参之后
- 接收单个参数,接收N个位置参数,转换成元组的形式
*变量名,在参数个数不固定的情况下使用
def test(x,*args):
print(x)
print(args)
- 调用方式一:test(1,2,3,4),将1赋给x,将“2,3,4”放到一个元组里面
- 调用方式二:test(*[1,2,3,4])
- 接收字典
**变量名,接收N个关键字参数转换成字典分方式
def test2(name,**kwargs):
print(kwargs)
- 调用方式一:test2("css",name="alex",age=8,sex="F"),结果为name的值为css,kwargs的值为{'name':'alex','age'=8,'sex'='F'}
- 调用方式二:test2(**{'name':'alex','age'=8,'sex'='F'})
- 接收单个参数,接收N个位置参数,转换成元组的形式
- 形参和实参
- 前向引用
函数调用之前必须已经声明,表现为在一个py文件中,调用函数的部分必须在该函数代码块之后,函数与函数之间的相互调用不存在这种情况。 - 全局变量和局部变量
局部变量只在函数内部生效,即一个函数就是这个变量的作用于
全局变量不能在函数中定义,但是函数中可以直接访问,不能修改。如果想在函数中修改或者定义全局变量,需要在变量之前加global, 这种方式绝对不要用。 列表、类、集合、字典除外,不需要global即可修改。 - 递归函数
在函数内部,调用自身的函数
- 递归特性:
- 必须有一个明确的结束条件
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 递归效率不高,递归层次过多会导致栈溢出
- 递归特性:
- 高阶函数
变量可以指向函数,函数的参数可以接受变量,那么一个函数就可以接收另一个函数作为参数,这个函数就称之为高阶函数
1 def add(a,b,f): 2 return f(a)+f(b) 3 res=add(3,-6,abs) 4 print(res)
- 编程方法
- 打印进度条
import sys,time
for i in range(20):
sys.stdout.write("#") #连续打印不换行
sys.stdout.flush() #将内存中的改变立马展示出来,和f.flush()同样的道理
time.sleep(0.1)
仰天大笑出门去,吾辈岂是蓬蒿人!