【python进阶】列表不应该总是第一选择,这几种序列类型比列表强大很多

请添加图片描述

文章目录

  • 引言
  • array数组
    • array的使用例子
  • 双向队列及其它队列
    • 双向队列
    • 不仅仅只有一种队列实现
  • 总结

引言

‍♂️作者简介:生鱼同学,大数据科学与技术专业硕士在读‍,曾获得华为杯数学建模国家二等奖,MathorCup 数学建模竞赛国家二等奖,亚太数学建模国家二等奖。

✍️研究方向:复杂网络科学

兴趣方向:利用python进行数据分析与机器学习,数学建模竞赛经验交流,网络爬虫等。

在学习python的过程中,我们首先接触到的序列是列表。但是,随着时间的推移我们会发现列表已经不能完全满足我们的需求了,这时就需要使用其它的数据类型来帮助我们完成不同的功能。话不多说,我们开始吧。

array数组

当我们存储过多的数据时,使用数组是一个好的选择。python中的数组和C语言中的数组同样简洁,创建一个数组需要一个类型编码来指定我们需要存储什么类型的数据,常用类型编码如下表所示:

类型编码 对应的C语言类型 对应的python类型 字节长度
b signed char int 1
B unsigned char int 1
u py_UNICODE Unicode character 2
h signed short int 2
H unsigned short int 2
i signed int int 2
I unsigned int int 2
l signed long int 4
L unsigned long int 4
q signed long long int 8
Q unsigned long long int 8
f float float 4
d double float 8

在上述表中,类型编码b只能存储一个字节长度的整型,范围从-128到127,这样当我们的序列里有很多数据的时候,可以帮我们节省大量的空间。

array的使用例子

在编码的过程中,我们可以快捷的利用array进行存取文件。当需要存储的内容过多的时候,利用列表通常会占用很大的内存并且到处文件后也会占有更多的空间。关于array快捷读写文件可以看下面这段代码:

from array import array
from random import random

# 创建100万个存有浮点数的数组
float_array = array('f', [random() for i in range(10**6)])
print(float_array[0])

# 将数字转换为bin文件
fp = open('float_array.bin','wb')
float_array.tofile(fp)
fp.close()

# 从bin文件中取内容
float_array_02 = array('f')
fp = open('float_array.bin','rb')
float_array_02.fromfile(fp, 10**6)
print(float_array_02[0])

>>> 0.2988782525062561
>>> 0.2988782525062561

可以看到,我们快捷的存取了文件。在数组类型中支持列表的大多数常用函数,包括但不限于append,extend等常规增删改的操作。

双向队列及其它队列

在我们需要一个队列的时候,我们可以利用列表的基础方法模拟队列先进先出的操作,例如下面的这个操作可以模拟队列:

list_deque = [i for i in range(10)]
print(list_deque)

# 模拟队列的操作
list_deque_item = list_deque.pop(0)
list_deque.append(100)
print(list_deque)

显然,这样的操作非常的复杂,而且本质上来讲其非常耗时,因为这会移动所有的元素位置。这时候我们就可以利用python内置的双向队列。

双向队列

使用python内置的collections 中的deque可以很好的解决上述的问题,并进行完全的队列操作,例如在左边或者右边添加元素。当然,这样的操作会使得队列中的其它元素被“挤出”队列中。请看下面的代码:

from collections import deque

# 创建一个队列,maxlen表示最大长度,设定后不可修改。
dq_example = deque([i for i in range(10)], maxlen=10)
print(dq_example)

# rotate会根据传入的参数n对队列进行修改
# 当n>0时,会把队列最右的n个元素放在左边
dq_example.rotate(3)
print(dq_example)
# 当n<0时,会把队列最左的n个元素放在右边
dq_example.rotate(-3)
print(dq_example)

dq_example.append(100)
print(dq_example)
# 在队列的左边添加元素
dq_example.appendleft(99)
print(dq_example)

dq_example.extend([199,200,201])
print(dq_example)
# 在队列的左边扩充队列
dq_example.extendleft([199,200,201])
print(dq_example)

>>>deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>>deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
>>>deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>>deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 100], maxlen=10)
>>>deque([99, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>>deque([3, 4, 5, 6, 7, 8, 9, 199, 200, 201], maxlen=10)
>>>deque([201, 200, 199, 3, 4, 5, 6, 7, 8, 9], maxlen=10)

可以看到,队列实现了列表中的大部分方法,而且其还有一些为队列专门定制的方法。例如rotate,expendleft等。

不仅仅只有一种队列实现

除了上述python内置的队列类型外,还有很多库实现了队列的操作。

  • queue:提供了Queue, LifoQueue, PriorityQueue,不同的线程可以利用其进行信息的交换。与此同时,该队列满员后不会抛弃旧的数据,而是把队列锁住等待空余。这种特性让它可以胜任多线程的线程控制工作,常常在多线程爬虫等应用中出现。
  • multiprocessing:与Queue类似,专门为了控制进程间的通信而设计。
  • asyncio:其为了协程而专门设计的队列,可以为异步协程的任务管理提供很好的便利。

总结

在本文中,我们介绍了列表不应该总是第一选择的时候,双向队列以及数组的使用方法。

如果你感觉本文对你很有帮助,请你帮我点赞评论收藏。如果你觉得有什么疑问或者是问题,可以在评论区与我讨论,我们下次再见。

【python进阶】列表不应该总是第一选择,这几种序列类型比列表强大很多_第1张图片

你可能感兴趣的:(Python进阶,python,开发语言)