Python序列数据类型

序列数据类型

分类

  • 容器序列:list、tuple、collections.deque,包含任何类型的引用
  • 扁平序列:str、bytes、bytearray、memoryview和array.array,存放的是值而不是引用,只能容纳一种类型
  • 可变序列:list、bytearray、array.array、collections.deque和memoryview
  • 不可变序列:tuple、str和bytes

列表推倒和生成器表达式

列表推导常用来创建列表

[s for s in symbols if s != 'a']

生成器用来创建数组、元组等其他序列类型,虽然列表推导也能实现,但序列推导是先创建序列再转成其他类型,而生成器表达式是利用迭代的方法逐个产生元素

for i in ('%s %s' % (x, y) for x in rows for y in cols)

生成器优点:它不是一次产生这10000种笛卡尔积组合,而是一个一个产生,因此在上式for循环中内存占用要小很多,速度也要更快,而且它可以生成列表以外的序列,工作原理请看第14章节

元组

有人叫元组为“不可变列表”,但其实元组更像某些数据的集合(看起来很像map),这样更能体现出元组拆包的特性

tips:

  • *t可以把一个可迭代对象t拆开作为函数的参数

  • 占位符_可以在拆包时帮忙处理元组中不感兴趣的数据

  • *agrs可以获取不确定数量的参数,最后得到的是一个list

    a,b,*rest=range(5)
    0,1,[2,3,4]
    
具名元组namedtuple
City = namedtuple('City', 'name country population coordinates')
tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
tokyo.coordinates

具名元组更像map,但是格式完全不一样,其实应该理解成一个只有数据没有方法的类。

创建namedtuple需要两个参数,第一个是类名,第二个是字段名,可以是空格分割的字符串,也可以是字符串组成的可迭代对象。

tips:

  • City._fields是一个包含City所有字段名的元组
  • City._make(Obj)是用一个可迭代对象Obj来生成City的实例,等同于City(*Obj)
  • City._asdict()是输出命名元组的方法

切片

s[start: stop :step]——取不到stop,所以len=stop-start,step可以为负数,那样就是从stop开始反着取,这样取不到start

切片对象slice(start, stop, step),在需要复用切片对象的时候很好用。

给切片赋值:注意一点,等号右边必须是一个可迭代对象,如[100]

I[2:5] = [20,30]

+和*:可用于所有的序列,+是把左右两个拼接起来,*是把该序列的元素复制n回

['_' * 3] * 3 = [['_', '_', '_'],['_', '_', '_'],['_', '_', '_']],但错误,因为它是把['_', '_', '_']的引用复制了3次,所以这三个其实是一个东西
改正就是用fori in range(3)每次新建引用
['_'] * 3 = ['_', '_', '_']是正确的,因为字符串是不可变对象,它是值不是引用

sort

list.sort()返回None,对list就地改动;sorted()返回一个新list

参数

  • reverse: True降序,False升序
  • key: 只有一个参数的函数

排序是稳定的

bisect和insort

bisect(haystack, needle)——在干草堆中找针的位置,返回index

haystack.insert(index, needle)——在index处插入新值

insort(seq, item)——在seq中插入item,一步到位且速度更快

列表的更优解

数组 array.array

当我们需要一个只包含数字的列表时,array比list更高效,因为它背后不是float对象,而是数字的机器翻译,和C语言中数组一样。

它是可变列表,所以它支持pop、insert、extend,以及文件操作tofile、fromfile,速度更快。

创建

from array import array
floats = array('d', (ramdom() for i in range(10**7)))
# 'd'是double类型,可迭代对象

文件

floats.tofile(open('floats.bin', 'wb'))
floats2 = array('d')
floats2.fromfile(open('floats.bin', 'rb'), 10**7)
# 写入二进制文件,按double格式读出10^7个数据

排序

a=array(a.typecode, sorted(a))
# 数组不在支持就地排序,只能新建一个数组

另一个快速序列化数字的方法是pickle模块,而且它可以处理几乎所有的内置数据类型,包含复数、嵌套集合,甚至用户自定义的类等,它的速度和array.tofile一样快

内存视图 memoryview

memoryview可以和array共享一块内存空间,然后memoryview.cast可以用不同的方式看待数据,和C语言中类型转换的概念差不多。

number = array.array('h', [-2,-1,0,1,2]) # 有符号字符
memv = memoryview(number)
memv_oct = memv.cast('B') # 无符号整数
# memv_oct.tolist() = [254,255,255,255,0,0,1,0,2,0]
memv_oct[5] = 4
# number = array('h', [-2,-1,1024,1,2])
NumPy和SciPy

很好做高维数组和矩阵的建立,以及相关的线性代数、数学分析等运算公式,详细请看其他文章

队列
collections.deque

它是一个线程安全,可以快速从两端头尾添加或删除元素的队列,但对中间元素操作较为缓慢。

dq = deque(range(10), maxlen=10)
# 可迭代对象,maxlen是可选参数,一旦设定不能修改

如果插入后超过maxlen,会自动从另一端顶出去一个元素

queue

它提供了同步(线程安全)的类Queue、LifoQueue和PriorityQueue,用于线程间交换信息。

不同于collection.deque的点在于Queue等在满员后会被锁住,知道有其他线程移除某元素,所以它可以用作任务管理,也可以用作生产者-消费者问题中的同步缓冲区

multiprocessing

它实现了自己的Queue,也是用于线程通信的,还有一个专门的multiprocessing.JoinableQueue类型,使任务管理更方便。

asyncio

Python 3.4 新提供的包,里面有 Queue、LifoQueue、PriorityQueue 和 JoinableQueue

heapq

它没有队列类,而是提供了heappush和heappop操作,把可变序列看作堆队列或者优先队列使用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值