day08-集合setdefault补充,集合和文件以及字符编码的介绍
今日内容:
字典setdefault()方法的案例补充:
我们都知道setdefault()方法是判断一个字典中是不是存在某个key,没有将括号内的key和value添加到字典中,有的话就不会动存在的key对应的字典,返回值的那个value也是一样的,key有就返回原来的value,没有就返回添加的.
案例:当key存在和不存在时,返回值的情况
stu_dic = {'name': "jkey", 'age': 18}
res = stu_dic.setdefault('sex', 'male')
print(res) # ===> male
print(stu_dic) # ===> {'name': 'jkey', 'age': 18, 'sex': 'male'}
stu_dic = {'name': "jkey", 'age': 18, 'sex': 'xxx'}
res = stu_dic.setdefault('sex', 'male') #
print(res) # ===> xxx
print(stu_dic) # ===> {'name': 'jkey', 'age': 18, 'sex': 'xxx'}
1.集合类型(set)
集合是一个无序的不重复元素序列
作用:去重,关系运算
定义方式:在{}内用逗号分隔开的多个元素,集合内元素的特点有三个:
- 集合元素必须是不可变类型
- 集合元素不能重复(重复了会去重)
- 集合元素是一个无序的
数据类型转换
创建格式:可以使用大括号{ }
或者 set()
函数创建集合
注意:创建一个空集合必须用 set()
而不是 { }
,因为 { }
是用来创建一个空字典。
s = set() # 定义一个空集合的方法
print(type(s)) # 类型为set
d = {} # 定义的是一个空字典.
s1 = {,} # 语法错误",",逗号俩边必须有值
小提示:
可变类型是不可hash类型
不可变类型是可hash类型
注意集合的目的是将不同的值存放到一起,不同的集合间用来做关系运算,无需纠结于集合中单个值
优先掌握的操作:
1、长度len
计算集合的值的个数,返回的是整数
s1 = {11, 22, 33}
print(len(s1)) # ==> 3
2、成员运算in和not in
判断一个对象在不在一个集合中,返回的是布尔值
print(11 in s1) # True
print(22 not in s1) # False
学习python和linux的学生俩个集合,后面方法会用到该例子
pythons = {'jkey','liu','song','egon','lxx'}
linuxs = {'song','li','jiang','egon','kong'}
3、并集|合集 俩个集合合并到一起--->所有学生的名字
print(pythons | linuxs) # {'lxx', 'song', 'jkey', 'kong', 'jiang', 'liu', 'egon', 'li'}
print(pythons.union(linuxs))
4、&交集:取俩个集合的共同部分==>即报名python又报名linux的学生
print(pythons & linuxs) # {'song', 'egon'}
print(pythons.intersection(linuxs))
pythons = pythons & linuxs
pythons.intersection(linuxs)
5.-差集:一个集合减掉另外一个集合共同的部分
print(pythons - linuxs) # {'jkey', 'liu', 'lxx'}
print(linuxs - pythons) # {'kong', 'li', 'jiang'}
print(pythons.difference(linuxs))
print(linuxs.difference(pythons))
6、交叉补集^对称差集:俩个集合相互相减,然后合并到一起==>取没有同时学俩门课程的学生
res = (pythons - linuxs) | (linuxs - pythons)
print(res) # {'jkey', 'kong', 'lxx', 'jiang', 'liu', 'li'}
print(pythons ^ linuxs) # {'jkey', 'kong', 'lxx', 'jiang', 'liu', 'li'}
print(pythons.symmetric_difference(linuxs))
7、== 判断俩个集合的值是不是相等
s1 = {11, 22, 33}
s2 = {22, 33, 44}
print(s1 == s2) # False
8、父集:>,>= # 判断一个集合包不包含另一个集合,如果一个集合a被另外一个集合b包含,那a就是b的子集,即b就是a的父集,如果俩个的包含关系是一样的,那它们互为对方的儿子或者爸爸
print(s1 >= s2) # False
print(s1.issuperset(s2)) # False
9、子集:<,<=
print(s2 <= s1) # False
print(s1.issubset(s2)) # False
需要掌握的
update()
功能:向一个集合中添加多个值,也可以是可迭代对象
s1 = {11, 22, 33}
update(obj) # 可以添加多个值
s1.update({55,66,77}) # 将一个集合添加到集合s1中
print(s1) # {33, 66, 22, 55, 11, 77}
add()
功能:向集合内添加一个值
s1.add(111) # 向s1集合添加一个值 为 111
print(s1) # {33, 11, 22, 111}
remove()
功能:根据元素的值删除,删除的元素不存在会报异常
s1.remove(22) # 根据元素的值删除,元素不存在会报异常
print(s1) # {33, 11}
s1.remove(2222) # 报错 keyerror
discard()
功能:也是根据元素的值删除,但删除的元素不存在不会报错
s1.discard(3333)
print(s1)
pop()
功能:随机删除集合中的一个值
s1.pop() # 随机删
print(s1) # {11, 22}
clear()
功能:清空集合内的元素
s1.clear() # 清空集合元素
print(s1) # {11, 22}
copy()
功能:浅copy,copy一个集合
s2 = s1.copy()
print(s2)
isdisjoint()
功能:判断俩个俩个集合的范围是不是不相干的,是就返回True,不是就返回一个False
print(s1.isdisjoint(s2))
文件处理
前言:
1、什么是文件
文件是操作系统提供给用户或者应用程序操作硬盘的一种机制,它是一种机制,并不是真正的文件
2、为何要用文件
我们要想将应用程序永久的保存起来,就必须要用文件,通过文件编写让操作系统去执行,对应的功能实现是操作系统帮你实现的.最典型的功能就是帮助我们将内存中的字符通过指定的字符编码表存到硬盘中,然后等在硬盘中取值到内存中,又是根据你存的时候的那张表二进制对应的字符反解码成指定的语言.
读写文件----->存取硬盘
具体由下面三个概念一起完成:
应用程序: open()
操作系统: 打开文件
计算机硬件: 硬盘空间
3、如何用文件
打开文件
读/写
关闭文件
前言:
open方法是由应用程序调用的,为的是让操作系统帮应用程序执行打开文件的操作,操作系统会先建立一个硬盘空间,去做你对文件的具体操作.
open() 方法
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。
open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。
open(file, mode='r')
完整的语法格式为:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:
- file: 必需,文件路径(相对或者绝对路径)。
- mode: 可选,文件打开模式
- buffering: 设置缓冲
- encoding: 一般使用utf8
- errors: 报错级别
- newline: 区分换行符
- closefd: 传入的file参数类型
- opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。
mode 参数有:
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
默认为文本模式,如果要以二进制模式打开,加上 b 。
File对象的属性
以下是和file对象相关的所有属性的列表:
属性 | 描述 |
---|---|
file.closed | 返回true如果文件已被关闭,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称。 |
file.softspace | 如果用print输出后,必须跟一个空格符,则返回false。否则返回true。File对象的属性 |
通过open()方法创建一个文件对象案例:
f = open(r"a.txt", mode="rt", encoding='utf-8')
# f的值-》文件句柄,文件对象
res = f.read() # 将f对象绑定的文件内的内容全部读出来,返回一堆字符串
print(res, type(res)) # 2352 45454 45532513 541514 <class 'str'>
f.close() # 回收操作系统的资源,回收的是操作系统的
print(f) # 因为python解释器会自动帮我们将没有使用的变量名回收,它会在最后一行执行完之前,应用程序f文件对象还是在内存中的,但最后会自动回收
# f.read() # ValueError: I/O operation on closed file.
with open()
功能:创建一个文件对象,但不用自己将操作系统的文件指令关掉,with 会帮我们自动回收
语法:with open(file_path,mode,encoding) as f:
- 其中file_path要操作系统打开的那种文件的路径(可以是绝对路径,也可以是相对路径)
- mode 表示 打开的文件的模式,可选参数,默认为 rt : r表示该文件内容只可以读,t表示该文件内容为文本,就是人类可以读懂的字符
- encoding 表示指定存/取的编码格式,可选参数,默认为'utf-8'
with open打开文件可以同时打开多个,以逗号分隔开
with open(r"a.txt", mode="rt", encoding='utf-8') as f, \ # \表示取消后面的\n表示和下方一个整体
open(r"b.txt", mode="rt", encoding='utf-8') as f1:
res = f.read()
案例,从账号密码文件中取出账户和密码
with open(r"a.txt", mode="rt", encoding='utf-8') as f:
for line in f:
res = line.strip('\n').split(':')
print(res)
字符编码(了解)
1.储备知识
运行python程序的三个步骤:python a.py
-
先启动python
-
解释器会将文本文件a.py内容由硬盘读入内存
-
解释器会解释执行刚刚读入内存的内容,识别python语法
2.什么是字符编码
概念: 字符编码(英语:Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数自然数/385394)序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信的传递。
人类的字符----------------->编码------------------>数字
数字-------------> 解码 ----------------> 人类的字符
3.为何要学习字符编码:
为了解决运行python程序三个接的中的2,3阶段有可能会出现的乱码问题.过程只要和字符相关的不管是编码还是解码都会有一个对应的字符编码表
4.字符编码表的发展史
一开始只有 ASCII 表,一家独大,编码和解码对应的表都只有一个,因为那时候只做到了英文字符和数字字符之间的转换,用户应用程序的字符和内存,硬盘之间可以直接转换.一个字节=8bit=一个字符
随着计算机的普及,每个国家又根据自己的需要,也创建了对应的字符编码表,像中国的GBK字符编码表,日本的shift_JIS...,它不仅支持用户输入自己国家的语言还都支持英文,由此它刷到硬盘中对应的字符编码表变成了多样,此时就存在编码和解码时对应的字符编码表不一样,就会导致乱码的出现. GBK中一个字符=>2个字节=>16bit
所有就有了后面的Unicode
Unicode
如果有一种编码,将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。这就是Unicode编码。
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,“汉”这个字的Unicode编码是U+6C49。
Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节字节)存储一个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。
utf-8
为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长短。比如英文字母可以只用1个字节就够了。
UTF-8的编码是这样得出来的,以”汉”这个字为例:
“汉”字的Unicode编码是U+00006C49,然后把U+00006C49通过UTF-8编码器进行编码,最后输出的UTF-8编码是E6B189。
但是由于计算机的发展.还有一些公司的硬盘中存取的还是之前按照自己国家的存的字符,如果都更新成了utf-8,那么这些硬盘中存取的数据就是一堆没有用的数据了,为了避免这个情况的发生,他们又将unicode当作一个过渡的字符编码表,它不仅有对应数字的关系还有对应各国字符编码对应的关系.
所以Unicode它有俩个历史意义,一个是统一了字符编码表,二是将之前按照不同的字符编码表存在硬盘中的数据一个过渡期.
结论:如何保证不乱码?
1.编码和解码必须参照同一张表
2.现在的内存中一般都是由unicode的格式,而存到硬盘中的为utf-8