python 遍历数组gbk编码_python bytes和bytearray、编码和解码
str、bytes和bytearray简介
str是字符数据,bytes和bytearray是字节数据。它们都是序列,可以进行迭代遍历。str和bytes是不可变序列,bytearray是可变序列,可以原处修改字节。
bytes和bytearray都能使用str类型的通用函数,比如find()、replace()、islower()等,不能用的是str的格式化操作。所以,如有需要,参考字符串(string)方法整理来获取这些函数的使用方法。
str
str将各个字符组合在一起,以一种不可变序列进行存储。但是在底层它还是一个个的二进制数,是由一个个的字节组成的(也就是byte),只不过python根据指定的字符集编码"强行"将字节序列显示为字符。
python 3.x中默认str是unicode格式编码的,例如UTF-8字符集。
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
unicode编码的str,意味着能够直接存储除ascii码外的很多字符,比如中文,比如欧洲的重音符号。还意味着可以将一个unicode字符存储为多个字节,并将连续多个的字节翻译成单个对应的字符。
>>> a = "我"
>>> a
'我'
>>> ord(a)
25105
>>> a.encode()
b'\xe6\x88\x91'
根据指定字符集,底层的字节序列和字符序列间的转换过程完全无需人为的参与,python已经做好了一切。
bytes
bytes是不可变的二进制格式字节数据(注意,是字节不是字符),以整数方式表示。例如对于ascii范围内的字符"a",它存储为97。
要构造bytes类型的数据,方法之一是在字符串前面加上b或B前缀。
例如:
>>> B = b"abcd"
>>> [i for i in B]
[97, 98, 99, 100]
>>> B[0] = "A"
Traceback (most recent call last):
File "", line 1, in
TypeError: 'bytes' object does not support item assignment
bytes和下面的bytearray都能使用str类型的绝大部分方法。例如find()、replace()等,但用法上可能会有所区别,比如str.replace()的替换参数期待的是字符,而bytes.replace()的替换参数可能是字节。例如:
>>> b'abcd'.replace(b'cd',b'XY')
b'abXY'
bytearray
bytearray是可变的二进制数据(byte)。
要构造bytearray对象,方法之一是将bytes数据作为bytearray()方法的参数,或者将str数据和编码作为参数。
例如:
>>> S = b"abcd"
>>> BA = bytearray(S)
>>> [ i for i in BA ]
[97, 98, 99, 100]
>>> BA[0] = 65
>>> BA
bytearray(b'Abcd')
unicode字符
单字节的字符(8bit位,共256个字符,ascii只用到了7个字节)能表示出来的字符毕竟有限,例如它没法表示出中文字符。
所以,各国设计了各种多字节的字符编码来表达自己国家的文字,底层仍然使用二进制数存储,然后通过设计好的编码表将二进制数转换成各种字符。比如中国有GBK的各种编码,还有全球通用的编码类型unicode、utf-8、utf-16等。
无论什么编码,内部都包含ascii编码(也有例外,比如utf-16),它只需单个字节。也就是说,ascii编码是任何其它编码表的子集。但有些编码表强制规定每个字符占多少个字节(比如unicode固定为2个字节),有些编码表动态决定每个字符占多少个字节(比如utf-8是变长的,可能占用1-4个字节空间,存储字母为1个字节,存储中文字符为3个字节)。
关于unicode和utf-X格式的编码关系,粗略地可以认为utf-X是unicode格式的一种特殊类型。实际上在存储utf数据时,内部会自动在Unicode和utf之间进行转换。
要构建Unicode类型,只需加上u或U前缀。
>>> U = u"我爱你"
>>> B = bytes(U,"utf-8")
>>> B
b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
>>> BA = bytearray(U,"utf-8")
>>> BA
bytearray(b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0')
编码和解码
下面一张图搞懂编码、解码、编码表之间的关系。
不难看出,它们是一种根据编码表进行翻译、映射的过程:
编码:str --> bytes
解码:bytes --> str
实际上,字符串类型只有encode()方法,没有decode()方法,而bytes类型只有decode()方法而没有encode()方法。
>>> set( dir(str) ) - set( dir(bytes) )
{'encode', ... , 'isidentifier', 'format'}
>>> set( dir(bytes) ) - set( dir(str) )
{'decode', 'hex', 'fromhex'}
二进制格式的数据也常称为裸数据(raw data),所以str数据经过编码后得到raw data,raw data解码后得到的str。
python中的编码、解码
上面说了,编码是将字符数据转换成字节数据(raw data),解码是将字节数据转换成字符数据。在Python中字符数据也就是字符串,即str类型,字节数据也就是bytes类型或bytearray类型。
编码时,可以使用字节类型的构造方法bytes()、bytearray()来构造字节,也可以使用str类型的encode()方法来转换。
解码时,可以使用str类型的构造方法str()来构造字符串,也可以使用bytes、bytearray()类型的decode()方法。
另外需要注意的是,编码和解码的过程中都需要指定编码表(字符集),默认采用的是utf-8字符集。
编码过程
例如,使用encode()的方式将str编码为bytes数据。
>>> str1 = "abcd"
>>> str2 = "我爱你"
# 默认编码
>>> str1.encode()
b'abcd'
>>> str2.encode()
b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
# 显式指定使用utf-8进行编码
>>> str1.encode("utf-8")
b'abcd'
>>> str2.encode("utf-8")
b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
# 使用utf-16编码
>>> str1.encode("utf-16")
b'\xff\xfea\x00b\x00c\x00d\x00'
>>> str2.encode("utf-16")
b'\xff\xfe\x11b1r`O'
# 使用gb2312编码
>>> str1.encode("gb2312")
b'abcd'
>>> str2.encode("gb2312")
b'\xce\xd2\xb0\xae\xc4\xe3'
# 使用gbk编码
>>> str1.encode("gbk")
b'abcd'
>>> str2.encode("gbk")
b'\xce\xd2\xb0\xae\xc4\xe3'
使用bytes()和bytearray()将str构造成bytes或bytearray数据,这两个方法都要求str->byte的过程中给定编码。
>>> bytes(str1,encoding="utf-8")
b'abcd'
>>> bytes(str1,encoding="utf-16")
b'\xff\xfea\x00b\x00c\x00d\x00'
>>> bytearray(str1,encoding="utf-8")
bytearray(b'abcd')
>>> bytearray(str2,encoding="utf-8")
bytearray(b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0')
实际上,bytes()、bytearray()这两个方法构造字节数据的时候还有点复杂,因为可以从多个数据源来构造,比如字符串、整数值、buffer。如何使用这两个方法构造字节数据,详细内容参考help(bytes)和help(bytearray)给出的说明,这里给几个简单示例。
构造bytes的方式:
# 构造空bytes对象
>>> bytes()
b''
# 使用str构造bytes序列,需要指定编码
>>> bytes("abcd",encoding="utf-8")
b'abcd'
# 使用int初始化5个字节的bytes序列
>>> bytes(5)
b'\x00\x00\x00\x00\x00'
# 使用可迭代的int序列构造字节序列
# int值必须为0-256以内的数
>>> bytes([65,66,67])
b'ABC'
# 使用bytes或buffer来构造bytes对象
>>> bytes(b'abcd')
b'abcd'
构造bytearray的方式:
# 构造空bytearray对象
>>> bytearray()
bytearray(b'')
# 使用bytes或buffer构造bytearray序列
>>> bytearray(b"abcd")
bytearray(b'abcd')
# 使用str构造bytearray序列,需要指定编码
>>> bytearray("abcd",encoding="utf-8")
bytearray(b'abcd')
# 使用int初始化5个字节的bytearray序列
>>> bytearray(5)
bytearray(b'\x00\x00\x00\x00\x00')
# 使用可迭代的int序列构造bytearray序列
# int值必须为0-256以内的数
>>> bytearray([65,66,67])
bytearray(b'ABC')
解码过程
解码是字节序列到str类型的转换。
例如,使用decode()方法进行解码"我"字,它的utf-8的编码对应为"\xe6\x88\x91":
>>> b = b'\xe6\x88\x91'
# 采用默认字符集utf-8
>>> b.decode()
'我'
# 显式指定编码表
>>> b.decode("utf-8")
'我'
使用str()进行转换。
>>> str(b,"utf-8")
'我'
关于乱码
当编码、解码的过程使用了不同的(不兼容的)编码表时,就会出现乱码。所以,解决乱码的唯一方式是指定对应的编码表进行编码、解码。
例如,使用utf-8编码"我"字,得到一个bytes序列,然后使用gbk解码这个bytes序列。
>>> "我".encode().decode("gbk")
Traceback (most recent call last):
File "", line 1, in
UnicodeDecodeError: 'gbk' codec can't decode byte 0x91 in position 2: incomplete multibyte sequence
这里报错了,因为utf-8的字节序列里有gbk无法解码的字节。如果使用文本编辑器一样的工具去显化这个过程,得到的将是乱码字符。
python 遍历数组gbk编码_python bytes和bytearray、编码和解码相关推荐
- python遍历数组获取下标_python获取list下标及其值的简单方法
python列表知道下标怎么取值在python中,如果知道列表下标,可以直接通过下标法(列表名[下标])来在python中,如果知道列表下标,可以直接通过下标法(列表名[下标])来取出该下标对应的列表 ...
- python遍历数组的两种方法及将print的内容写入文件中
python遍历数组的两种方法 第一种,最常用的,通过for in遍历数组 colours = ["red","green","blue"] ...
- python 遍历数组的3种方法及常用的代码
1.直接使用数组的元素进行遍历,但这种遍历方法效率较低,不推荐使用.可以使用 python中的 num或者 int数组. 2.使用 python中的my_num,该方法通过数组的末尾进行遍历,效率最高 ...
- python遍历数组的方法小结
这篇文章主要介绍了python遍历数组的方法,实例总结了两种Python遍历数组的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例总结了python遍历数组的方法.分享给大家供大家参考.具体分析 ...
- python3(4)--- python遍历数组的两种方法
python遍历数组的两种方法 第一种,最常用的,通过for in遍历数组.其实本质就是取出来的是这个数组或者列表中的元素,和角标无关. colours = ["red",&quo ...
- python遍历数组的两种方法的代码
工作过程中,把开发过程中较好的一些内容段备份一下,下面内容是关于python遍历数组的两种方法的内容,希望对小伙伴有用途. colours = ["red","green ...
- Python 遍历数组元素
数组(Array)是有序的元素序列. 若将有限个类型相同的变量的集合命名,那么这个名称为数组名.组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量.用于区分数组的各个元素的数字编号 ...
- python遍历数组的代码
将写内容过程比较常用的一些内容片段珍藏起来,如下内容段是关于python遍历数组的内容,应该对大伙有所用处. items = [ 1, 2, 3, 4, 5 ] for i in items: pri ...
- python遍历数组的方法
python遍历数组的两种方法 1.for in arrays= ["昨天","今天","明天"]for array in arrays:p ...
- python遍历数组的两种方法_python同时遍历数组的索引和值的实例
你想在迭代一个序列的同时跟踪正在被处理的元素索引. 获取索引 内置的 enumerate() 函数可以很好的解决这个问题: >>> my_list = ['a', 'b', 'c'] ...
最新文章
- string转成对象_JAVA学习分享[008]——面向对象深化(一)
- 10个实用的但偏执的Java编程技术
- 为什么要学 Flink,Flink 优势在哪?
- 基于ROS的移动机器人开发:视觉、语音、导航
- Eclipse在线安装SVN插件
- Nginx实战|Nginx健康检查
- 线性代数 : 矩阵消元
- 有道云笔记markdown教程
- 用C语言/C++实现一个基础的电话簿
- Integer类型的比较
- 密码朋克的社会实验(一):开灯看暗网
- win10安装CH341SER.INF 失败 且没有COM口问题(德飞莱CH340T)
- adb 读取短信,通话记录、日历、通讯录等的方法
- O365结合ADFS限制用户登录地址 (二) - 安装AAD Connect
- Axure8原型设计实战案例:如何实现登录功能和用户管理?8年专业产品经理设计分享
- 解决Paradox Interactive系列游戏加载mod时的路径问题
- Python在Linux 目录的常用操作命令
- OutOfMemoryError系列(3): Permgen space
- 【诗经】之《秦风·蒹葭》
- 多变量分析”——数据挖掘、数据分析
热门文章
- C# 反序列化datetime的处理
- C#中Abstract和Virtual
- 树形DP+二分(Information Disturbing HDU3586)
- c++中的list用法[转]
- oracle中插入一个blob数据
- node.js + express服务端,客户端请求图片,在浏览器出现乱码解决方案
- CICD详解(十一)——sonar详解
- HDOJ-1232 畅通工程
- WPA3 标准被曝严重漏洞,WiFi 密码可遭窃取?
- 复习Javascript专题(三):面向对象(对象的创建与继承,原型及原型链)