1.集合 使用{}存储
主要作用:
①去重,把两个列表变成集合,就自动去重了
②关系测试,测试两组数据之前的交集、差集、并集等关系
将列表转化为集合,set命令强制转换即可
关系运算:
交集:intersection命令 或 &
并集:union命令 或 |
差集:difference命令 或 -
子集:issubset命令
父集:issuperset命令
对称差集:symmetric_difference命令 或 ^,对于A、B两个集合,该命令输出为A∪B-A∩B(将两个集合里分别独有的元素取出来放在一起)
判断两集合是否有相同元素:isdisjoint命令
#以上操作不更改原集合
#以下操作更改原集合
添加一项元素:add命令
添加多项元素:update命令配合列表
删除一项元素:remove命令(元素不存在报错)/discard命令(元素不存在返回None)/pop命令 随机删除,返回删除的元素值
长度:len命令
判断元素在集合内:in 命令
判断元素不在集合内: not in命令
intersection_update:求交集并将其更新在原集合中(intersection是生成在新集合中不改变原集合)
difference_update、symmetric_difference_update同理

1 list1 = [1, 3, 4, 7, 5, 3, 9] 2 A = set(list1) 3 print(list1, type(list1)) 4 list2 = [2, 22, 66, 4, 7, 55] 5 B = set(list2) 6 print('集合A:', A, '\n', '集合B:', B) 7 print("\033[31m下面是集合操作\033[0m".center(30, '-')) 8 # 交集 9 print('A、B求交', A.intersection(B), A & B) 10 # 并集 11 print('A、B求并:', A.union(B), A | B) 12 # 差集 13 print('A-B:', A.difference(B), A - B) 14 print('B-A:', B.difference(A), B - A) 15 # 子集 16 print('A是B的子集?', A.issubset(B)) 17 # 父集 18 print('A是B的父集?', A.issuperset(B)) 19 # 对称差集 20 print('对称差集', A.symmetric_difference(B), A ^ B) 21 # 判断两集合是否有相同元素 22 print(A.isdisjoint(B)) 23 print("\033[31m结束\033[0m".center(30, '-')) 24 print(A, B) # 上述集合操作并未更改原集合 25 26 # 添加一项元素 27 A.add('WK') 28 print(A) 29 # 添加多项元素 30 A.update([444, 666, 888]) 31 print(A) 32 # 删除一项元素 33 A.remove('WK') 34 print(A) 35 # 某元素是否在集合内 36 print("WK" in A) 37 print("WK" not in A) 38 print(A.pop()) 39 print(A) 40 A.discard(888) 41 print(A)

1 [1, 3, 4, 7, 5, 3, 9] <class 'list'> 2 集合A: {1, 3, 4, 5, 7, 9} 3 集合B: {2, 66, 4, 7, 22, 55} 4 -------下面是集合操作------- 5 A、B求交 {4, 7} {4, 7} 6 A、B求并: {1, 2, 3, 4, 5, 66, 7, 9, 22, 55} {1, 2, 3, 4, 5, 66, 7, 9, 22, 55} 7 A-B: {1, 3, 5, 9} {1, 3, 5, 9} 8 B-A: {2, 66, 22, 55} {2, 66, 22, 55} 9 A是B的子集? False 10 A是B的父集? False 11 对称差集 {1, 2, 66, 3, 5, 9, 22, 55} {1, 2, 66, 3, 5, 9, 22, 55} 12 False 13 ---结束,上述操作并未更改原集合---- 14 {1, 3, 4, 5, 7, 9} {2, 66, 4, 7, 22, 55} 15 {1, 3, 4, 5, 'WK', 7, 9} 16 {1, 3, 4, 5, 'WK', 7, 9, 888, 666, 444} 17 {1, 3, 4, 5, 7, 9, 888, 666, 444} 18 False 19 True 20 1 21 {3, 4, 5, 7, 9, 888, 666, 444} 22 {3, 4, 5, 7, 9, 666, 444}
2.文件操作
打开文件:
open(‘文件名’) 可指定打开方式(只读、读写……)、编码方式(encoding = ‘编码方式’)、等
文件读写:
不同的打开方式对比如下:
模式 | 描述 |
t | 文本模式 (默认) |
x | 写模式,新建一个文件,如果该文件已存在则会报错 |
b | 二进制模式 |
+ | 打开一个文件进行更新(可读可写) |
U | 通用换行模式(不推荐) |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写 |
二进制模式常用于网络传输
r+读写模式的一个注意点:如果打开后不读直接写,会从头开始覆盖;如果读一部分(指针不在开始位置了),再写就会变成追加
读取一行:readline命令 读取某几行:循环加判断即可 (文件操作时,务必注意打开方式)
读取全部:readlines命令 将文档内容读取至列表内
查看指针位置:tell命令
读取指针回归文件开始位置:seek(0)
其他:
isatty命令:文件是否连接到一个终端设备
fileno命令: 返回一个整型的文件描述符(file descriptor FD 整型),可用于底层操作系统的 I/O 操作
encoding命令:文件编码方式
name命令:返回文件名称
seekable命令:文件读取指针是否可移动
readable\writale命令:文件是否可读/可写
flush命令:用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,但有时需要在关闭前刷新它,这时就可以使用 flush() 方法。

1 # low loop 打印yesterday文档内的第36行内容 2 f = open('yesterday', encoding='utf-8') # 文件句柄 3 for i, line in enumerate(f.readlines()): # readlines命令将文档内容读取并存储至列表内 4 if i == 35: 5 print(line.strip()) 6 else: 7 continue 8 f.close() 9 # 用以上readlines命令,要先将所有内容读取一遍到内存里/或readline命令,最后也是把所有内容都存到内存里,故只能处理小文档 10 11 # 改进 12 f = open('yesterday', encoding='utf-8') 13 count = 0 14 for line in f: 15 count += 1 16 if count == 36: 17 print(line.strip()) 18 else: 19 continue 20 f.close() 21 # 用以上命令,内存每次存储一行内容(涉及迭代器,后续学习) 22 23 f = open('yesterday', encoding='utf-8') 24 f.readline() 25 print(f.tell()) # 查看指针位置 26 print(f.readline().strip()) 27 f.seek(0) # 指针回归文件开头 28 print(f.readline().strip()) 29 f.close() 30 31 f = open('yesterday', 'r+', encoding='utf-8') 32 print(f.tell()) 33 f.write('奇奇怪怪') 34 print(f.tell()) 35 f.close() 36 37 f = open('yesterday', 'r+', encoding='utf-8') 38 f.readline() 39 f.write('奇奇怪怪') 40 print(f.tell()) 41 f.close()
有趣的小例子:打印进度条

1 import sys 2 import time 3 4 for i in range(100): 5 sys.stdout.write('*') # print每次输出后会自动换行 6 sys.stdout.flush() # 即时刷新缓冲区而非完成后统一写入 7 time.sleep(0.1) # 推迟执行的秒数,使输出过程显示更清晰
truncate命令:截断命令(截断位置后的内容清除) 可以指定开始位置,不指定则从头开始(指定位置时不以指针位置为标准,始终从头开始计算)
文件修改:
思路:如果全部读取至内存中,对于大文件来说,耗时太长且可能内存不够;故逐行读取,对不需修改的内容,直接读取并写入另一文件,对需要修改的内容,修改后写入另一文件,最终生成的新文件为内容修改后的文件(故修改过程需要两个文件)

1 f = open('yesterday', 'r', encoding='utf-8') 2 f_new = open('yesterday_new', 'w+', encoding='utf-8') 3 4 for line in f: 5 if "奇奇怪怪" in line: 6 line = line.replace("奇奇怪怪", "When I was young (当我小时候)") 7 f_new.write(line) 8 f.close() 9 f_new.seek(0) 10 update = f_new.read() 11 f = open('yesterday', 'w', encoding='utf-8') 12 f.write(update) 13 f.close() 14 f_new.close()
with语句:
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
with open(‘文件名’,’打开方式’,encoding = ‘编码方式’) as …:(可通过逗号隔开同时打开多个文件)
文件操作…
执行完毕自动关闭文件
3.字符编码与转码
详细文章:https://www.cnblogs.com/luotianshuai/articles/5735051.html
查看当前默认编码方式:导入sys模块后用sys.getdefaultencoding命令
查看编码方式:chardet模块下detect命令