10 基本数据类型之集合 字符编码

基本数据类型之集合 字符编码

1 集合

1.1 什么是集合?

无序的不重复元素序列称为集合。

1.2 集合的定义

可以使用大括号 { } 或者 set() 定义集合
特征:

  1. 集合内元素必须为不可变数据类型
  2. 集合内元素无序
  3. 集合内元素无重复
s1 = {1, 1, 'aaa', (1, 2)}  # {1, (1, 2), 'aaa'}
s2 = set('abc')  # {'c', 'b', 'a'}

s3 = set([1, 'a'])
s4 = set([1, ['a']])  # 报错 列表属于可变数据类型

定义空集合必须使用函数set()
{ } 表示定义一个空字典

1.3 集合的使用

使用集合类型时,需要把这个容器作为整体去考虑。
集合不可以通过索引的方式访问元素,因此一般不用于对单个元素进行存取。
一般用于去重操作关系运算

1.3.1 去重操作

注意:

  1. 待去重对象中的元素必须为不可变数据类型
  2. 去重后无法保证原来的顺序
s = 'abcacbcabcba'
print(set(s))  # {'b', 'c', 'a'}
l = ['a', 'b', 'c', 'b', 'a']
print(set(l))  # {'a', 'b', 'c'}
1.3.2 关系运算

基本关系运算包括交,差,并,补等。

1.3.2.1 交集

获取两个或更多集合中都包含的元素

  1. &
    返回一个新集合-交集
  2. set.intersection(set1, set2 … etc)
    返回一个新集合-交集
  3. set.intersection_update(set1, set2 … etc)
    修改当前集合,返回None
    可以理解为在当前集合上移除不重叠的元素
s1 = {1, 2, 3}
s2 = {2, 3, 1, 4}
s3 = {5, 6, 7, 1}
print(s1 & s2 & s3)  # {1}
print(s1.intersection(s2, s3))  # {1}
print(set.intersection(s1, s2, s3))  # {1}
print(s1)  # {1, 2, 3}
print(s1.intersection_update(s2, s3))  # None
print(s1)  # {1}
1.3.2.2 差集

返回的集合元素包含在第一个集合中,但不包含在其它集合

  1. -
    返回一个新集合-差集
  2. set.difference(set)
    返回一个新集合-差集
  3. set.difference_update(set)
    修改当前集合,返回None,
    可以理解为从当前集合中移除这些集合中都存在的元素。
s1 = {1, 2, 3}
s2 = {2, 3, 1, 4}
s3 = {5, 6, 7, 1}
print(s1 - s3)  # {1}
print(s1 - s2 - s3)  # set()
print(s1.difference(s2))  # {2, 3}
print(set.difference(s1, s3))  # {2, 3}
print(s1)  # {1, 2, 3}
print(s1.difference_update(s3))  # None
print(s1)  # {2, 3}
1.3.2.3 并集

包含了所有集合的元素,重复的元素只会出现一次

  1. |
    返回一个新集合-并集
  2. set.union(set1, set2…)
    返回一个新集合-并集
  3. set.update(set)
    修改当前集合,返回None,
    可以理解为当前集合添加新的元素
s1 = {1, 2, 3}
s2 = {2, 3, 1, 4}
s3 = {5, 6, 7, 1}
print(s1 | s3)  # {1, 2, 3, 5, 6, 7}
print(s1.union(s3))  # {1, 2, 3, 5, 6, 7}
print(set.union(s1, s3))  # {1, 2, 3, 5, 6, 7}
print(s1)  # {1, 2, 3}
print(s2.update(s1, s3))  # None
print(s2)  # {1, 2, 3, 4, 5, 6, 7}
1.3.2.4 对称差集

返回多个集合中不重复的元素集合

  1. ^
    返回一个新集合-对称差集
  2. set.symmetric_difference(set)
    返回一个新集合-对称差集
  3. set.symmetric_difference_update(set)
    移除当前集合中在其它指定集合中相同的元素,并将其它指定集合中不同的元素插入到当前集合中
s1 = {1, 2, 3}
s2 = {2, 3, 1, 4}
s3 = {5, 6, 7, 1}
print(s1 ^ s3 ^ s2)  # {1, 4, 5, 6, 7}
# 这里s1.symmetric_difference()只能接受一个参数
print(s1.symmetric_difference(s3))  # {2, 3, 5, 6, 7}
# 这里set.symmetric_difference()只能接受两个参数
print(set.symmetric_difference(s1, s3))  # {2, 3, 5, 6, 7}
print(s1)  # {1, 2, 3}
# 这里s2.symmetric_difference_update()只能接受一个参数
print(s2.symmetric_difference_update(s1))  # None
print(s2)  # {4}
1.3.2.5 集合之间的关系

相交、包含、不相交

s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = {1, 2, 3}
print(s1.isdisjoint(s2))  # False 判断两个集合是否不相交,即没有相同元素
print(s1.issubset(s2))  # False 判断s1是否是s2的子集
print(s1.issuperset(s2))  # False 判断s1是否是s2的父集

# 判断父子集
print(s1 > s2)  # False
print(s1 < s2)  # False
print(s1 > s3)  # False
print(s1 == s3)  # True
print(s1 >= s3)  # True
1.3.3 其它操作
  1. 集合元素个数 len()
s = {'a', 'b', 'c'}  
print(len(s))  # 3
  1. 成员运算 in/not in
  2. 循环遍历
for s in {1, 2}:
	# 代码块
  1. 删除元素
    删除集合中指定的元素

set.discard(item)
返回None,移除一个不存在的元素时不做任何处理

set.remove(item)
返回移除的元素,移除一个不存在的元素时会抛出异常

set.pop()
随机移除一个元素

  1. 增添
    set.add(item)
    为集合增添元素
1.4 基本数据类型分类总结
1.4.1 存值数量
  1. 只能存储一个值(标量,原子类型)
    数字,字符串
  2. 可以存储多个值(容器类型)
    列表,元组,字典,集合
1.4.2 访问方式
  1. 直接访问
    只能通过变量名访问整个值:数字
  2. 顺序访问
    可以通过索引访问指定元素,索引对应值,代表顺序,也可以称为序列类型
    字符串,列表,元组
  3. 键访问
    可以通过键访问指定元素,索引对应值,无序,也可以称为映射类型
    字典
1.4.3 可变/不可变类型
  1. 可变数据类型
    列表,字典,集合
  2. 不可变数据类型
    数字,字符串,元组

2 字符编码

2.1 字符编码简介

文本文件的内容以及python的字符串类型数据等都与字符编码相关

2.1.1 计算机三大核心硬件:CPU,内存,硬盘
  1. 软件运行前代码及其相关数据存放于硬盘中;
  2. 软件启动时将硬盘中的数据加载到内存中,CPU从内存中读取相应的指令并执行;
  3. 软件在运行过程中产生的数据都是先存储于内存中,需要永久保存数据则将数据从内存写入到硬盘中。
2.1.2 软件读取文本文件的流程

文件编辑器读取文本文件的执行流程

  1. 启动一个文件编辑器
  2. 文件编辑器会将文件内容从硬盘加载到内存中
  3. 文本编辑器会将刚刚读入内存中的内容显示到屏幕上

python解释器的执行流程
前两步与文本编辑器相同。
第三步:
python解释器解释执行读入内存中的内容,并开始识别python语法。

2.1.3 字符编码的由来

人类可以识别多种字符,但计算机底层硬件只能识别二进制数字。
因此人类需要将自己的字符翻译成二进制数字再交给计算机。
翻译需要遵循标准,这个标准称为字符编码表,表中存放着人类的字符与数字的对应关系

2.1.4 常用的字符编码

ASCII
((American Standard Code for Information Interchange) 美国信息交换标准代码
诞生于1967年,主要用于显示现代英语和其他西欧语言,一共包括128个字符,一个字符对应8位二进制数 (8 bit / 1 Bytes)。

GB2312
信息交换用汉字编码字符集 1980年

GBK
汉字编码扩展规范 1995年
一个字符对应16位二进制数 (2 Bytes)

Unicode
统一码、万国码、单一码

  1. 为每种语言中的每个字符设定了统一且唯一的二进制编码;
  2. 作为其它编码格式的中转站,与其它编码都有映射关系,因此Unicode编码可以与其它编码相互转换。
    一个字符对应16位二进制数 (2 Bytes)

utf-8
Universal Character Set/Unicode Transformation Format
针对Unicode的一种可变长度字符编码,可以降低IO延迟
一个字符对应 1 ~ 3 Bytes

2.1.5 文本文件的读与写

  1. 通过文本编辑器输入文字后,文字转化为Unicode格式的二进制数据存放于内存中,保存时将这些二进制数据写入硬盘中

  2. 将硬盘中Unicode格式的二进制数据加载到内存中,然后通过ASCII表翻译成文字。

内存中使用Unicode编码,可以修改的是存入硬盘中的编码格式,即将内存中的数据从Unicode编码转化成需要的编码格式。

Unicode编码可以与其它编码相互转换,但是其它编码不能通过Unicode编码进行互转。

2.2 文件头
  1. 读取文件时(解释器)

python3 解释器默认的字符编码为utf-8 (读取)
python2 解释器默认的字符编码为ASCII (读取)

文件头
可以在文件首行指定文件头,修改默认的读取字符编码

# coding: gbk

解释器在读取第一行文件头时使用自己默认的编码,而无论是python3的utf-8还是python2的ASCII,都支持英文和基本符合(#, -等),然后再按照文件头指定的编码格式来读取接下来的文件内容。

  1. 存储文件时
    文本编辑器控制文件按照哪一种字符编码格式进行存储。

核心:文件头指定的编码格式必须与存储文件时的编码格式一致。

2.3 字符串存储格式

对于python解释器的执行流程第三部分,即开始识别语法并执行,当遇到字符串时,也可能出现乱码情况。

t = 'Hello, world.'

变量定义会在内存中开辟空间,并将字符串值存入。
内存中的编码都是unicode编码格式的数据。因此最方便的是将字符串以unicode编码格式存入内存空间中,这样不会出现乱码问题。
在python3中,字符串类型数据默认直接存储为unicode格式,不会出现乱码。
在python2中,按照文件头指定的编码格式来存储字符串类型的值。
如果文件头中没有指定编码,那么python2的解释器会按照默认的编码方式(ASCII)存储。对于中文等非ASCII表中的文字会出现乱码问题。
解决方法:
字符串类型数据前加u,表示将字符串强制以unicode的编码格式进行存储。

s = u'你好。'  # 此时即便文件头为utf-8,s的值依然以unicode的编码格式存储

在python3中,字符串以unicode的编码格式进行存储。

2.4 编码与解码
2.4.1 bytes类型

bytes 类型是Python 3中新增加的数据类型,代表一些字节的集合,两个十六进制数构成一个byte,以b开头的字符串属于bytes类型。

2.4.2 编码与解码
  1. 编码
    str.encode(encoding=‘utf-8’)
    将字符串从unicode的编码格式转换为指定的编码格式
  2. 解码
    str.decode(encoding=‘utf-8’)
    将字符串从指定的编码格式转换为unicode编码格式

encode:str --> bytes
decode:bytes --> str

str1 = '你好Hello'
str2 = str1.encode('gbk')
print(str2)  # b'\xc4\xe3\xba\xc3Hello' bytes类型
str3 = str2.decode('gbk')
print(str3)  # 你好Hello str类型

另一种方式

  1. 编码 bytes
  2. 解码 str
data_str = 'Hello, world.'
# str --> bytes
data_bytes = bytes(data_str, encoding='utf-8')

# bytes --> str
data_str = str(data_bytes, encoding='utf-8')
2.5 总结

避免乱码问题

  1. python3
    使用utf-8编码格式保存文件,就什么也不需要做。
    否则需要为文件添加文件头声明文件存储的编码方式。
  2. python2
    为文件添加文件头声明文件存储的编码方式
    字符串前加u
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值