一篇文章弄懂Python中所有数组数据类型
Python  /  管理员 发布于 7年前   169
前言
数组类型是各种编程语言中基本的数组结构了,本文来盘点下Python中各种“数组”类型的实现。
其实把以上类型都说成是数组是不准确的。这里把数组当作一个广义的概念,即把列表、序列、数组都当作array-like数据类型来理解。
注意本文所有代码都是在Python3.7中跑的^_^
0x00 可变的动态列表list
list应该是Python最常用到的数组类型了。它的特点是可变的、能动态扩容,可存储Python中的一切对象,使用时不用指定存储的元素的类型。
使用非常简单
>>> arr = ["one","two","three"]>>> arr[0]'one'# 动态扩容>>> arr.append(4)>>> arr['one', 'two', 'three', 4]# 删除一个元素>>> del arr[2]>>> arr['one', 'two', 4]
0x01 不可变的tuple
tuple的操作与list类似。它的特点是不可变,不能扩容,可存储Python中的一切对象,使用时不用指定存储的元素的类型。
>>> t = 'one','two',3>>> t('one', 'two', 3)>>> t.append(4)AttributeError: 'tuple' object has no attribute 'append'>>> del t[0]TypeError: 'tuple' object doesn't support item deletion
tuple可以使用+运算符,这个运算将创建一个新的tuple对象用于存储数据。
>>> t+(1,)('one', 'two', 3, 1)>>> tcopy = t+(1,)>>> tcopy('one', 'two', 3, 1)>>> id(tcopy)4604415336>>> id(t)4605245696
可以看出tuple执行+运算符之后两个对象的地址是不一样
0x02 array.array
如果在Python中要用到其它语言中类似“数组”的数据结构,就需要用到array模块了。它的特点是可变的、存储相同类型的数值,不能存储对象。
因为array在使用的时候要指定元素数据类型,因此它比list和tuple都有比较高效空间性能。
# 使用时指定元素数据类型为`float`>>> arr = array.array('f', (1.0, 1.5, 2.0, 2.5))>>> arrarray('f', [1.0, 1.5, 2.0, 2.5])# 修改一个元素>>> arr[1]=12.45>>> arrarray('f', [1.0, 12.449999809265137, 2.0, 2.5])# 删除一个元素>>> del arr[2]>>> arrarray('f', [1.0, 12.449999809265137, 2.5])# 增加一个元素>>> arr.append(4.89)>>> arrarray('f', [1.0, 12.449999809265137, 2.5, 4.889999866485596])# 如果将一个字符串类型数据存储到一个浮点数的数组将会报错>>> arr[0]='hello'TypeError: must be real number, not str
array中元素的数据类型可以参考下表
Type code | C Type | Python Type |
---|---|---|
'b' | signed char | int |
'B' | unsigned char | int |
'u' | Py_UNICODE | Unicode character |
'h' | signed short | int |
'H' | unsigned short | int |
'i' | signed int | int |
'I' | unsigned int | int |
'l' | signed long | int |
'L' | unsigned long | int |
'q' | signed long long | int |
'Q' | unsigned long long | int |
'f' | float | float |
'd' | double | float |
0x03 字符串序列str
Python3中使用str对象来表示一个文本字符序列(看,这跟Java中的字符串String是多么相似呢)。它的特点不可变的Unicode字符序列。
在str中它的每一个元素都是字符串对象。
>>> s ='123abc'>>> s'123abc'>>> s[0]'1'>>> s[2]'3'# 字符串是不可变的序列,不能删除其中的元素>>> del s[1]TypeError: 'str' object doesn't support item deletion # 要对字符串进行操作,可以转化成list >>> sn = list(s)>>> sn['1', '2', '3', 'a', 'b', 'c']>>> sn.append(9)>>> sn['1', '2', '3', 'a', 'b', 'c', 9]# 字符串中的元素也是字符串对象>>> type(s[2])<class 'str'>>>> type(s)<class 'str'>
str对象也可以执行+操作,它也会生成一个新对象用于存储。
>>> s2 = s+'33'>>> s2'123abc33'>>> id(s2)4605193648>>> id(s)4552640416
0x04 bytes
bytes对象用于存储字节序列,它的特点是不可变存储,可存储0-256的数值。
>>> b = bytes([0,2,4,8])>>> b[2]4>>> bb'\x00\x02\x04\x08'>>> b[0]=33TypeError: 'bytes' object does not support item assignment>>> del b[0]TypeError: 'bytes' object doesn't support item deletion
0x05 bytearray
bytearray对象与bytes类似,用于存储字节序列。它的特点是可变的,能动态扩容的字节数组。
>>> ba = bytearray((1,3,5,7,9))>>> babytearray(b'\x01\x03\x05\x07\t')>>> ba[1]3# 删除一个元素>>> del ba[1]>>> babytearray(b'\x01\x05\x07\t')>>> ba[0]=2>>> ba[0]2# 添加一个元素>>> ba.append(6)# 只能添加字节>>> ba.append(s)TypeError: 'str' object cannot be interpreted as an integer>>> babytearray(b'\x02\x05\x07\t\x06')# 字节的范围是0-256>>> ba[2]=288ValueError: byte must be in range(0, 256)
bytearray可以转化成bytes对象,但效率不是很高。
# bytearray转成bytes将生成一个新对象>>> bn = bytes(ba)>>> id(bn)4604114344>>> id(ba)4552473544
0x06 各个类型相互转化
tuple->list
>>> tuple(l)('a', 'b', 'c')
list->tuple
>>> t('a', 'b', 'c')>>> list(t)['a', 'b', 'c']
str->list
>>> l = list('abc')>>> l['a', 'b', 'c']
list->str
>>> l['a', 'b', 'c']>>> ''.join(l)'abc'
str->bytes
>>> s = '123'>>> bytes(s)TypeError: string argument without an encoding>>> bytes(s,encoding='utf-8')b'123'# 或者使用str的encode()方法>>> s.encode()b'123'
bytes->str
>>> b = b'124'>>> bb'124'>>> type(b)<class 'bytes'>>>> str(b,encoding='utf-8')'124'# 或使用bytes的decode()>>> b.decode()'124'
0x07 总结
这些数据类型都是Python自带的,在实际开发中应该根据具体需求选择合适的数据类型。例如当要存储的元素类型是多种多样的,那么就应该使用list或者tuple。而array.array相对来说拥有较好的空间性能,但它只能存储单一类型。
我相信在很多业务场景中list或tuple是可以满足需求的,只是其它数据结构也要有所了解,在我们做一些基础组件时,会考虑数据结构的性能,或者阅读他人的代码时,能做到心中有数。
0x08 学习资料
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家的支持。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号