本篇涉及内容
set集合
set是一个无序的且不重复的元素集合
1、创建set集合的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # 第一种方法s = set()print(type(s)) # 输出<class 'set'> # 第二种方法s = {1, 2}print(type(s)) # 输出<class 'set'> # 第三种方法# 将一个可迭代的序列转换成为集合l1 = [11, 22, 33, 44, 22, 44]s = set(l1)print(type(s))print(s) # 输出<class 'set'>{33, 11, 44, 22} # 注:可以看到输出的set集合里面每一个值都是唯一的,这也体现出了set集合是一个不重复的序列 |
2、set集合的一些方法
add() 向set集合中添加一个元素12345678910111213# add() 向set集合中添加一个元素s={1,2}print(s)s.add(3)s.add(3)s.add(2)print(s)# 输出{1,2}{1,2,3}# 注:set的add方法一次只能够添加一个元素,由于set集合有去重的机制,所以多次添加相同的值,最后输出set集合的时候也只会显示一次clear() 清空set集合中的所有元素
12345678s={1,2,"a","b","c"}print(s)s.clear()print(s)# 输出{'b',1,2,'a','c'}set()copy() 浅拷贝
1234567891011121314151617x=[11,22,33,11,44,22,55]s=set(x)print(s)print(id(s))# 输出内存地址# 对s进行浅拷贝s2=s.copy()print(s2)print(id(s2))# 输出内存地址# 输出{33,11,44,22,55}5882152# 内存地址{33,11,44,22,55}6091272# 内存地址# 注:可以看到s和s2的内存地址已经发生变化了
difference() 将前者存在,后者不存在的值取出来赋值给一个新的变量
123456789s1={11,22,33,44}s2={22,33,44,55}s3=s1.difference(s2)print(s3)# 输出{11}# 注:将s1中存在,s2中不存在的元素放到一个新的set集合中,然后返回给s3difference_update() 将前者存在,后者不存在的元素放到一个新的set集合中,然后将前者直接覆盖掉
1234567891011s1={11,22,33,44}s2={22,33,44,55}s3=s1.difference_update(s2)print(s1)print(s3)# 输出{11}None# 注:将s1中存在的元素,s2中不存在的元素放到一个新的set集合中,然后将前者直接覆盖掉,不返回值discard() 删除set集合中的一个元素
123456789s1={11,22,33,44}s1.discard(11)s1.discard(111)print(s1)# 输出{33,44,22}# 注:如果删除的值不存在,也不会出现报错信息intersection() 前者和后者都有的
123456789s1={11,22,33,44}s2={22,33,44,55}s3=s1.intersection(s2)print(s3)# 输出{33,44,22}# 注:可以理解为两个集合的并集吧intersection_update() 前者和后者都有的,赋值给前者 没有返回值
123456789s1={11,22,33,44}s2={22,33,44,55}s1.intersection_update(s2)print(s1)# 输出{33,44,22}# 注:将s1清空,把s1和s2中都存在的元素赋值给s1isdisjoint() 判断两个集合是否有相同的元素,如果有,则返回False 否则返回True
12345678910111213141516s1={11,22,33,44}s2={55}s3=s1.isdisjoint(s2)print(s3)# 输出Trues1={11,22,33,44}s2={22,33,44,55}s3=s1.isdisjoint(s2)print(s3)# 输出Falseissubset() 判断前者是否是后者的子集,返回一个布尔值
123456789101112131415161718s1={11,22,33,44}s2={44}s3=s1.issubset(s2)print(s3)# 输出Falses1={44}s2={11,22,33,44}s3=s1.issubset(s2)print(s3)# 输出True# 注:就是判断前者中的所有元素在后者中是否都存在,返回一个布尔值issuperset() 判断前者是否是后者的父集,返回一个布尔值
123456789101112131415161718s1={11,22,33,44}s2={44}s3=s1.issuperset(s2)print(s3)# 输出Trues1={44}s2={11,22,33,44}s3=s1.issuperset(s2)print(s3)# 输出False# 同issubset()方法正好相反pop() 随机删除一个set集合中的元素,并返回该元素, 如果该集合为空,则报错
123456789101112131415161718s1={11,22,33,44}s2=s1.pop()print(s1)print(s2)# 输出{11,44,22}33# 如果从空集合中执行pop方法,则会报错s1=set()s2=s1.pop()# 错误信息Traceback (most recent call last):File"D:/SVN/learning/s13/day3/class_code/set集合.py", line218,in<module>s2=s1.pop()KeyError:'pop from an empty set'remove() # 从集合中删除一个指定的元素,如果该元素不存在,则报错,可以直接忽略该方法,直接用上面介绍的discard方法,删除元素不会报错,没有返回值
123456789101112131415161718s1={11,22,33,44}s1.remove(11)print(s1)# 输出{33,44,22}# 使用remove删除一个不存在的元素s1={11,22,33,44}s1.remove(111)print(s1)# 输出Traceback (most recent call last):File"D:/SVN/learning/s13/day3/class_code/set集合.py", line222,in<module>s1.remove(111)KeyError:111symmetric_difference # 前者有后者没有 和后者有,前者没有的 都取出来放到一个新的集合中并返回
1234567s1={11,22,33,44}s2={22,33,44,55}s3=s1.symmetric_difference(s2)print(s3)# 输出set([11,55])symmetric_difference_update 前者有后者没有 和后者有,前者没有的 都取出来放到一个新的集合中覆盖前者, 没有返回值
1234567s1={11,22,33,44}s2={22,33,44,55}s1.symmetric_difference_update(s2)print(s1)# 输出set([11,55])union() 返回一个新的集合,返回一个集合,包含前者和后者所有的元素
1234567s1={11,22,33,44}s2={22,33,44,55}s3=s1.union(s2)print(s3)# 输出set([33,11,44,22,55])update() 将后者的元素全部添加到前者中, 没有返回值
1234567s1={11,22,33,44}s2={22,33,44,55,1,2,3,4}s3=s1.update(s2)# update中接受一个可以迭代的对象,可以是字典、元组、字符串、set集合print(s1)# 输出set([33,2,3,4,1,11,44,22,55])
函数
一、函数的定义
函数就是为了避免重复造轮子,避免造成代码量的冗余以及让代码的维护更简单
简单来说,比如我有一个功能需要应用在10个地方,如果不用函数来实现的话,我就需要在10个地方将这个功能的代码都写一遍,这个时候你的老板说这个功能要加一个小的功能进去,这个时候你就崩溃了,在这10个地方写的代码都需要修改,如果使用函数的话,就只需要修改这个用函数封装起来的代码就可以了
二、函数的语法和创建
语法
1234567def函数名(参数):...函数体...返回值# 返回值不是必须的,如果没有return语句,则默认返回值None创建一个函数
1234deftest():# 创建一个名为test的函数print("hello")# 函数体输入"hello"test()# 调用函数,会执行test函数的函数体
三、参数
1 2 3 4 5 6 | python中函数的参数主要分为以下几种:1、普通参数2、默认参数3、指定参数4、动态参数5、万能参数 |
普通参数
12345678defsend(name, content):# name 和 content是形式参数,简称形参print(name, content)returnTruesend("zhangsan","DaShaX")# 调用函数 "zhangsan" 和 "DaShaX" 是实际参数,简称实参# 输出zhangsan DaShaX
默认参数
1234567891011# 默认参数只能在形式参数的最后出现,否则会报错defsend(name, content="DaShaX"):print(name, content)returnTrue# 调用函数send("zhangsan")# 输出zhangsan DaShaX指定参数
12345678910111213defsend(name, content):print(name, content)returnTrue# 调用函数send(content="DaShaX", name="zhangsan")# 输出zhangsan DaShaX# 注:在调用函数时,指定形参对应的实参,可以不按照函数形参的顺序进行调用动态参数
123456789101112131415161718192021222324252627282930动态参数主要包括两种:*args# 接收一个可迭代的数据类型**kwargs# 接收一个含有键值对的数据类型使用动态参数的好处主要是不需要指定参数的个数### *args 对传进来的可迭代参数将其进行迭代,将迭代后的值组成一个元组deff1(*args):print(args,type(args))li=[1,2,3,4]f1(*li)# 输出(1,2,3,4) <class'tuple'>### **kwargs将传进来的字典或者键值对,保存到一个字典中deff1(**kwargs):print(kwargs,type(kwargs))dic={'k1':'v1','k2':'v2'}f1(**dic)# 或者通过下面这种形式调用# f1(k1='v1', k2='v2') 得到的输出结果是一样的# 输出{'k1':'v1','k2':'v2'} <class'dict'>万能参数
1234567891011121314151617# 万能参数是由动态参数的两种形式组合而成,*args在前,**kwargs在后def f1(*args, **kwargs):print(args, type(args))print(kwargs, type(kwargs))f1(11,22,33,44, k1="v1", k2="v2") # 调用函数# 或者使用下面的方式进行调用,效果是一样的# l1 = [11,22,33,44]# d1 = {"k1":"v1","k2":"v2"}# f1(*l1, **d1)# 输出(11,22,33,44) <class'tuple'>{'k2':'v2','k1':'v1'} <class'dict'>动态参数的应用
123456789# 对字符串的format()方法进行传参的时候可以使用动态参数来完成,下面两种传参得到的结果都是一样的s1="i am {0}, age {1}".format("zhangsan",20)print(s1)s2="i am {0}, age {1}".format(*["zhangsan",20])print(s2)# 输出i am zhangsan, age20i am zhangsan, age20
四、return语句
return是函数执行的返回值,在函数执行的过程中,遇到return的时候,函数就结束了,并且返回对应的值,如果return没有定义返回值,则为None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 创建两个函数,一个有返回值,一个没有返回值def f1(a1 , a2): return def f2(a1, a2): return a1 + a2 a1 = 5a2 = 10ret1 = f1(a1, a2) # 接收到的是Noneret2 = f2(a1, a2) # 接收到的是15print(ret1)print(ret2) # 输出None15 |
五、变量作用域
全局变量
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980###定义在函数外面的变量为全局变量,全局变量使用大写来表示,例如:NAME="zhangshan"### 在函数中可以直接调用全局变量来使用,但是不能对其进行重新赋值NAME="zhangshan"deff1():age=18print(age, NAME)f1()# 输出18zhangshan### 如果全局变量为列表,字典或集合,在函数中可以对其进行修改,但是不能对其进行重新赋值,字符串不能进行任何操作# 全局变量为列表,在函数中对其进行append操作NAMES=["zhangshan","lisi","wangwu"]# 全局变量deff1():age=18NAMES.append("dasha")# 在函数中对全局变量进行操作print(age, NAMES)f1()# 调用函数print(NAMES)# 输出在函数内被操作的全局变量# 输出18['zhangshan','lisi','wangwu','dasha']['zhangshan','lisi','wangwu','dasha']# 当全局变量为字典时,在函数中对其添加一对键值对NAMES={"zhangshan":18,"lisi":20,"wangwu":100}deff1():age=18NAMES["DaShanPao"]=200print(age, NAMES)f1()print(NAMES)# 输出18{'lisi':20,'DaShanPao':200,'wangwu':100,'zhangshan':18}{'lisi':20,'DaShanPao':200,'wangwu':100,'zhangshan':18}# 当全局变量为set集合时候,在函数中对其进行add操作NAMES=set(["zhangshan","lisi","wangwu"])deff1():age=18NAMES.add("sss")print(age, NAMES)f1()print(NAMES)# 输出18{'lisi','wangwu','sss','zhangshan'}{'lisi','wangwu','sss','zhangshan'}# 如果希望在函数内对全局变量进行重新赋值时,就需要在函数内使用global关键字对变量进行声明NAMES=["zhangshan","lisi","wangwu"]deff1():globalNAMESNAMES="DaShanPao"print(age, NAMES)f1()print(NAMES)# 输出['zhangshan','lisi','wangwu']DaShanPaoDaShanPao# 注:可以看到在函数中对全局变量NAMES使用global关键字进行声明,# 然后对该变量进行修改,在函数外进行输出时输出的是修改过的值局部变量
1234567891011121314151617181920212223242526272829### 定义在函数内的变量为局部变量,局部变量使用大写来表示,例如:deff1():NAME="zhangshan"print(NAME)f1()print(NAME)# 输出Traceback (most recent call last):File"D:/SVN/learning/s13/day3/class_code/函数.py", line142,in<module>print(NAME)NameError: name'NAME'isnotdefinedzhangshan# 注:在函数内定义的变量为局部变量,在函数外使用函数内的变量是会报错的### 要想让函数内的变量在函数外使用需要用global进行声明deff1():globalNAMENAME="zhangshan"print(NAME)f1()print(NAME)# 输出zhangshanzhangshan
六、自定义函数及函数规范
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | def login(username, password): """ 用于用户登录 :param username: 用户输入的用户名 :param password: 用户输入的密码 :return: True:表示登录成功 False:表示登录失败 """ f = open("db", "r") for line in f: line_list = line.split("|") if line_list[0] == username and line_list[1] == password: return True return False def register(username, password): """ 用户用户注册 :param username: 用户输入的用户名 :param password: 用户输入的密码 :return: None """ f = open("db", 'a') temp = "
" + username + "|" + password f.write(temp) f.close() def main(): t = input("1:登录 2:注册") if t == "1": user = input("请输入用户名:") pwd = input("请输入密码:") r = login(user, pwd) if r: print("登录成功") else: print("登录失败") elif t == "2": user = input("请输入用户名:") pwd = input("请输入密码:") register(user, pwd) |
七、lambda表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # lambda表达式就是简单函数的缩写# 例如def f1(a1): return a1 + 100 # 使用lambda表达式可以简写为:f2 = lambda a1: a1 + 100 # 也可以有两个参数,还可以有默认参数# f2 = lambda a1, a2=0: a1 + a2 + 100 # 对函数的调用ret = f1(10)print(ret) ret2 = f2(9)print(ret2) # 输出110110 |
八、python内置函数
python中有许多内置的函数 --> 点我查看python3内置函数官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ### abs(x) 取绝对值print(abs(-10))# 输出10 ### all(iterable) 返回一个bool值,传入一个可迭代的值,该值内的每一个元素都为真,才为真n = all([1, 2, 3])print(n)# 输出True n = all([1, 2, 3, 0])print(n)# 输出False ### any(iterable) 返回一个bool值,传入一个可迭代的值,该值内只要有一个元素都为真,就为真n = any([1, 0, False])print(n)# 输出True n = any([False, 0])print(n)# 输出False ### bool([x]) 返回一个布尔值 True 或 False x为可选,x为空时候,返回Falsex = 1x2 = 0ret = bool(x)ret2 = bool(x2)print(ret)print(ret2) # 输出TrueFalse ### bin(number) # 将十进制转换成二进制number = 10ret = bin(number)print(ret) # 输出0b1010 ### oct(number) 将十进制转换成为八进制number = 9ret = oct(number)print(ret) # 输出0o11 ### hex() # 将十进制转为十六进制number = 15ret = hex(number)print(ret) # 输出0xf ### bytes() 将字符串转换成为对应编码格式的字节类型name = "张三"ret = bytes(name, encoding="utf-8")print(ret)print(str(ret, encoding="utf-8")) # 使用str() 将字节类型转换为字符串类型,编码格式需要对应 ret = bytes(name, encoding="gbk")print(ret)print(str(ret, encoding="gbk")) # 使用str() 将字节类型转换为字符串类型,编码格式需要对应 # 输出b'xe5xbcxa0xe4xb8x89'张三b'xd5xc5xc8xfd'张三 |
三元运算
1 2 3 4 5 6 7 8 9 | # 三元运算就是对 if else的简写# 例如:if i == 1: name = "zhangshan"else: name = "SB" # 使用三元运算简写如下name = "zhangsan" if 1 == 1 else "SB" |
文件处理
打开文件
123456789101112131415161718192021# 打开文件# 第一种方法f=open("文件名(绝对路径或相对路径)","方法", encoding="utf-8")# 打开文件的时候一定要指定字符集# 第二种方法withopen("文件名(绝对路径或相对路径)","方法", encoding="utf-8") as f:# with下面的代码块执行完毕,自动关闭文件# 方法主要包括以下几种:"r"# 只读,文件必须存在,如果不存在,则报错"w"# 只写,如果文件存在,则清空,如果不在,则创建"x"# 如果文件存在,则报错,如果不存在,创建文件并只写"a"# 追加,如果文件存在,在文件末尾写,如果不存在,则先创建文件"rb"# 二进制读,以字节码方式表示,文件必须存在,如果不存在,则报错"wb"# 二进制写,以字节码方式表示,如果文件存在,则清空,如果不在,则创建"xb"# 二进制打开文件,以字节码方式表示,如果文件存在,则报错,如果不存在,创建文件并只写"ab"# 二进制打开文件,以字节码方式表示,追加,如果文件存在,在文件末尾写,如果不存在,则先创建文件"r+"# 读写 可读,可写 # 一般都用这个 先读在写,可以调整指针位置,然后在写入"w+"# 写读 可读,可写 # 先清空文件,在可读可写"x+"# 写读 可读,可写"a+"# 写读 可读,可写 # 不管指针在哪里,永远写到最后面操作文件
123456789101112f.read([number,])# 无参数,读全部,看参数number是否有值,有b 读字节, 无b,读字符f.write()# 写数据,当前指针位置写入文件 有b 写字节, 无b,写字符f.seek()# 调整当前指针的位置(字节)f.tell()# 获取当前指针的位置(字节)f.fileno()# 检测文件是否发生变化f.flush()# f.write会将内容写入到内存中,f.flush 会强制将内存中的内容写入到文件中f.readable()# 判断文件句柄是否可读 返回一个布尔值f.seekable()# 判断指针是否可以移动 返回一个布尔值f.writeable()# 判断文件句柄是否可写 返回一个布尔值f.readline()# 每次读取一行f.readlines()# 将文件中的内容存放到一个列表中,每一行为一个元素f.truncate()# 将文件进行截断,将指针后面的内容清空关闭文件
12f.close()如果使用with打开文件,with下面的代码块执行完毕,文件会自动关闭
练习代码
1234567891011# 循环文件每一行f=open("文件名","r+", encoding="utf-8")forlineinf:# 循环文件句柄,可以得到每一行的内容print(line)# 通过with同时打开两个文件,从第一个文件将内容读出,写入到第二个文件withopen("文件1","r", encoding="utf-8) as f1, open("文件2", "w", encoding="utf-8") as f2:forlineinf1:f2.write(line)