Dayday up ---- python Day3
集合:
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
list_1 = [1,3,5,7,9,11] #定义数值列表
list_2 = [1,2,3,4,5,6,7,8,9,10,11,12]
list_1 = set(list_1) #把列表转换成集合
list_2 = set(list_2)
Hi = set("hello") #创建一个字符串集合
print(list_1)
print(list_2)
print(Hi)
>>> {1, 3, 5, 7, 9, 11}
>>> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
>>> {'e', 'l', 'h', 'o'}
可以看出集合是去重 并且无序的
其他操作
list = list_1.intersection(list_2) #取两个集合的交集
list = list_1 & list_2 #交集的另一种符号表示:&
print(list)
>>> {1, 3, 5, 7, 9, 11}
list = list_1.union(list_2) #取两个集合的并集
list = list_1 | list_2 #并集的另一种符号表示:|
print(list)
>>> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
list = list_2.difference(list_1) #取两个集合的差集,在list_2里面却不在list1里面
list = list_2 - list_1 #差集的另一种符号表示: -
print(list)
>>> {2, 4, 6, 8, 10, 12}
list = list_1.issubset(list_2) #判断list_1是否是list_2的子集
print(list)
>>> True
list = list_2.issuperset(list_1) #判断list_2是否是list_1的父集
print(list)
>>> True
list_1 = [1,3,5,7,9,11,13] #定义数值列表
list_2 = [1,2,3,4,5,6,7,8,9,10,11,12]
list_1 = set(list_1) #把列表转换成集合
list_2 = set(list_2)
list = list_2.symmetric_difference(list_1) #取两个集合的对称差集,即项在t或s中,但不会同时出现在二者中,把互相都没有的取出来
list = list_1 ^ list_2 #对称差集的另一种符号表示: ^
print(list)
>>> {2, 4, 6, 8, 10, 12, 13}
print(list_1.isdisjoint(list_2)) #判断两个集合是否有交集,没有交集返回True
print(list_1.isdisjoint(Hi))
>>> False
>>> True
print(list_1)
list_1.add(999) #添加一项
print(list_1)
list_1.update([777,888]) #添加多项
print(list_1)
>>> {1, 3, 5, 7, 9, 11, 13}
>>> {1, 3, 5, 7, 999, 9, 11, 13}
>>> {1, 3, 5, 7, 999, 9, 777, 11, 13, 888}
print(list_2)
list_2.remove(9) #删除9 ,天生去重,如果不存在会报错
list_2.pop() #任意删除一个元素
list_2.discard(9) #删除9 ,天生去重,如果不存在则不会报错
print(list_2)
>>> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
>>> {2, 3, 4, 5, 6, 7, 8, 10, 11, 12}
print(3 in list_1) #测试3是否是list_1的成员
print(2 not in list_1) #判断2是否不是list_1的成员
>>> True
>>> True
文件操作
data = open("a.txt").read() #打开文件,并且读取全部内容,打开文件3.0以上为open,2.7以上为file
print(data)
如果a.txt里面有中文的话打印出来会有乱码,因为文件默认打开是gbk编码,python是utf-8编码,utf-8处理不了gbk的编码
正常为:
data = open("a.txt",encoding="utf-8").read()
print(data)
file = open("a.txt",encoding="utf-8") #称为文件句柄,打开的文件对象赋值为变量,包含文件的字符集文件大小以及在硬盘的起始位置
print(file.read())
#打开文件规范
# f = open("文件名","操作模式","指定字符编码")
# 默认是读模式 即 r 为读
# 写模式 w 如果有同名文件则覆盖重新写入内容,如果是没有这个文件则新建文件,不能读
# 追加模式 a 追加在文件的最末尾,不能读
file = open("a.txt","w",encoding="utf-8")
file.write("哈哈哈哈")
file = open("a.txt","a",encoding="utf-8") #追加
file.write("\n呵呵呵呵")
file.close() #关闭文件
f = open("a.txt","r",encoding="utf-8")
print(f.readline()) #读取文件的第一行
print(f.readline(3)) #第二次读取文件的第二行前3个字符
# for i in range(5):
# print(f.readline()) #读取文件前5行
# for i in range(10): #读取5-10行
# if i < 5:
# pass
# f.readline()
# elif i >10:
# pass
# else:
# print(f.readline())
# for line in f.readlines(): #读取所有行(直到结束符 EOF)并返回列表,一行一行的读
# print(line.strip()) #去掉换行
# 这种方式只适合小文件,会把所有读出来的数据存储到内存
# 以下这种方式比较靠谱
# count = 0
# for line in f:
# if count == 9:
# print("----------------")
# count +=1
# print(line)
# count +=1
# print(f.tell()) # 返回文件的当前位置读/写指针,字符位置
# print(f.read(5)) # 读5个字符
# f.seek(0) # 光标起始位置
# f.seek(30) # 回去从光标起始位置的第10个字符位置
# f.detach() # 编辑的过程中改变字符编码
# print(f.encoding) # 打印文件字符编码
# print(f.buffer) # 显示buffer对象
# print(f.errors) # 做异常处理使用
# print(f.fileno()) # 文件编号,调用操作系统的io编号
# print(f.isatty()) # 查看是否是一个终端设备
# print(f.seekable()) # 判断文件光标能否可以位置偏移
# print(f.readable()) # 判断文件是否可读
# print(f.writable()) # 判断文件是否可写
# f.flush() #作用是保持实时一致性,默认一般情况下是先存到内存等内存满了然后再存到硬盘,flush 是直接存到硬盘强制刷新
# print(f.buffer())
# print(f.closed) #判断文件是否关闭
# f.truncate() #默认截取当前位置
# f.truncate(2) #从文件开头截断2个字符包括空格
# r+ 既能读也能写,先读后追加或先读后写
# w+ 写读,先创建文件再写最后读
# a+ 追加读
# rb 读二进制文件,python3 网络传输只能用二进制格式 ,python2可以写字符
# wb 写二进制文件
#为了避免忘记关闭文件
# with open("a.txt","r",encoding="utf-8") as f:
# for line in f:
# print(line)
修改文件
with open("a.txt","r",encoding="utf-8") as f:
with open("a.txtbak", "w", encoding="utf-8") as f_new:
for line in f:
if "肆意的快乐" in line:
line = line.replace("肆意的快乐等我享受","肆意的快乐等alex享受")
f_new.write(line)
字符转码

import sys
print(sys.getdefaultencoding()) #打印当前的字符编码
s = u"您好" #u 表示unicode
print(s)
print(s.encode("utf-8").decode("gbk")) #转换成gbk
函数
三种编程方式:
面向对象: 类 class
面向过程: 过程 def ,没有返回值的函数,把一段过程功能定义到def里面
函数式变成: 函数 def
编程语言中的函数是逻辑结构化和过程化的一种编程方法
函数格式
python中函数定义方法:
def test(x):
"The function definitions"
x+=1
return x
def:定义函数的关键字
test:函数名
():内可定义形参
"":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
x+=1:泛指代码块或程序处理逻辑
return:定义返回值
函数的作用:
代码的重复利用
保持一致性
可扩展性
例子:
import time #导入时间模块
def logger_test():
with open("a.txt","a+") as f:
time_format = '%Y-%m-%d %X' #定义时间格式
time_current = time.strftime(time_format) #接收以时间元组,并返回以可读字符串表示的当地时间,格式由参数time_format决定
f.write('\ntime %s end action' % time_current)
def test1():
print("test1 starting action")
logger_test() #调用函数
def test2():
print("test2 starting action")
logger_test()
def test3():
print("test3 starting action")
logger_test()
test1() #调用函数
test2()
test3()
函数返回值
def test1():
"test1"
pass
def test2():
"test2"
return 0
def test3():
"test3"
return 0,10,'hello',['ll',22],{"yy":"beijing"}
test1() #直接调用不显示返回值
test2()
test3()
print(test1()) #print 显示返回值
>>> None
print(test2())
>>> 0
print(test3())
>>> (0, 10, 'hello', ['ll', 22], {'yy': 'beijing'})
# 返回值个数如果=0,返回None
# 返回值个数如果=1,返回object
# 返回值个数如果>1,返回tuple
return 可以返回函数即return test2
定义返回值的意义: 想要函数的执行结果,后面的执行需要返回值的结果
函数调用:
调用方法:
test()执行,()表示调用函数test,()内可以有参数也可没有
参数:
1.形参和实参
形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应)
实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参
区别:形参是虚拟的,不占用内存空间,.形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参
2.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)
def test(x,y): # x,y 为形参
print(x)
print(y)
print(x*y)
test(5,6) # 5,6为实参, 位置参数调用,顺序与形参必须得一一对应
test(y=5,x=7) # 根据关键字调用,与形参顺序无关
test(5,y=8) # 既有位置参数调用,关键字调用,默认用位置参数调用,关键字参数不能写在位置参数前面
3.默认参数
def test(y,x=9): #默认参数必须得放在形式参数的后面
print(x*y)
test(2) # 不定义x,就是用默认参数
test(2,8) # 定义x,就是用定义的参数
test(x=6,y=4) # 传参的个数不能大于形参个数
4.参数组
# 结果为元组:
def test(*args): # *args代表功能代号,表示实参不固定,*args 接受N个位置参数定义为元组,传参的时候可以为空
"参数组1"
print(args)
test(1,2,3,4,5,6) # 两种表现形式
test(*[1,2,3,4,5,6]) # *args = *[1,2,3,4,5,6] = tuple([1,2,3,4,5,6])
test()
# 结果为字典:
def test2(**kwargs): # **kwargs: 接受N个关键字参数转换为字典的方式
"参数组2"
print(kwargs)
print(kwargs['name'])
print(kwargs['age'])
test2(name="ll",age="22") # key=value,结果为字典格式
test2(**{'name':'ll','age':'22'})
def test3(**kwargs):
"参数组3"
print(kwargs['name']) #定义键名
print(kwargs['age'])
test3(**{'name':'ll','age':'22'}) #直接返回value值
def test4(name,**kwargs):
"位置参数,参数组"
print(name)
print(kwargs)
test4('ll',age='22') # name 必须要指定,**kwargs必须指定关键字参数
def test5(name,age=22,**kwargs): # 顺序为 形式参数,默认参数,参数组
"位置参数,默认参数,参数组"
print(name)
print(age)
print(kwargs)
test5("ll",sex="girl",age=21) #位置参数必须对应,关键字参数顺序不用
test5("ll",14,sex="girl")
def test6(name,age=22,*args,**kwargs):
"位置参数,默认参数,参数组"
print(name)
print(age)
print(args)
print(kwargs)
test6("ll",sex="girl",age=21) # args为空
test6("ll",14,1,2,3,sex="girl") # args为1,2,3
局部变量,全局变量
局部变量: 只在函数中生效,这个函数就是这个变量的作用域
全局变量: 在整个程序中生效的变量
name = "ll"
def change_name(name):
print("before change:",name) #全局变量的值
name = "yy"
print("after change",name) #局部变量的值
change_name(name)
print("what's your name?\n",name) #还是ll,全局变量的值
局部改全局
name = "ll"
def change_name():
global name # 局部变量声明改成全局变量,但是最好少用
name = "yy"
print("after change",name)
print(name) #在调用函数之前不生效
change_name()
print(name) #生效
#局部改全局,只有字符串和整数可以修改
#不能在函数更改列表,字典,集合,类等数据结构
递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归最大次数是 999
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
def calc(n):
print(n)
if int(n/2) > 0: # 判断条件
return calc(int(n/2)) #调用自身函数
calc(10)
高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(a,b,f): # 定义 a,b,f 形参
return f(a)+f(b)
res = add(3,-6,abs) # abs内置方法,赋值给f,取绝对值
print(res)

浙公网安备 33010602011771号