当前位置: 首页 > news >正文

python数组和队列

一、数组

如果一个列表只包含数值,那么使用array.array会更加高效,数组不仅支持所有可变序列操作(.pop、.insert、.extent等),而且还支持快速加载项和保存项的方法(.fromfile、.tofile等)

创建array对象时要提供类型代码,它是一个字母,用来确定底层使用什么C类型存储数组中各项,并且指定类型后,不允许向数组中添加与指定类型不同的值。类型码如下所示:

TypecodeC Typepython Typesize in bytes

'b'

signed char

int1
'B'unsigned charint1
'h'signed shortint2
'H'unsigned shortint2
'i'signed intint2
'I'unsigned intint2
'l' (lower L)signed longint4
'L'unsigned longint4
'q'signed long longint8
'Q'unsigned long longint8
'f'float(单精度浮点数)float4
'd'double(双精度浮点数)float8

示例:创建、保存、加载一个大型浮点数数组

from array import array
from random import random# 创建一个双精度浮点数数组
floats = array('d', [random() for i in range(10**7)])
print(floats[-1])       # output: 0.6150799221528432
# 将数组写入文件
with open('floats.bin', 'wb') as fp:floats.tofile(fp)floats2 = array('d')
# 从二进制文件中读取1000万个数并赋值给float2
with open('floats.bin', 'rb') as fp:floats2.fromfile(fp, 10**7)
print(floats2[-1])      # output: 0.6150799221528432
print(floats == floats2)        # output: True

处理大型数值时使用数组的优势

1.效率高:在使用array.tofile和array.fromfile时,发现二者的运行速度非常快,读取时无须使用内置函数float一行一行解析,比从文本文件中读取快;保存文件也比一行一行写入文本文件快很多。

2.占用内存少:保存1000万个双精度浮点数的二进制文件占80 000 000个字节(一个双精度浮点数占8字节);保存相同数据量文本文件占181 515 739字节。

补充:array类型没有列表那种就地排序算法sort,如果需要对数组进行排序,需要使用内置函数sorted重新构建数组

from array import arraynum = array('i', sorted([12, 432, 5, 6]))
print(num)      # output: array('i', [5, 6, 12, 432])

二、memoryview

内置的memoryview类是一种共享内存的序列类型,可以在不复制字节的情况下处理数组的切片,对处理大型数据集来说是非常重要的。

memoryview允许python代码访问支持缓冲协议的对象的内部数据,而无需复制(内存视图直接引用目标内存)。支持缓冲协议的对象:在python中有某些对象可以包装对底层内存阵列或缓冲区的访问,包括内置对象bytes和bytearray以及一些如array.array的扩展类型。

示例:展示如何将同一个6字节数组处理为不同的视图

from array import arrayoctets = array('B', range(6))
m1 = memoryview(octets)
# .tolist()表示将缓存区内的数据以一个列表的形式返回
print(m1.tolist())      # output: [0, 1, 2, 3, 4, 5]
# 根据前一个memoryview对象构建一个新的memoryvie对象,并转换为2行3列
m2 = m1.cast('B', [2, 3])
print(m2.tolist())      # output: [[0, 1, 2], [3, 4, 5]]
# 转换为3行2列
m3 = m1.cast('B', [3, 2])
print(m3.tolist())      # output: [[0, 1], [2, 3], [4, 5]]
m2[1, 1] = 22
m3[1, 1] = 33
# 显示原数组,证明octets、m1、m2、m3之间的内存是共享的
print(octets)       # output: array('B', [0, 1, 2, 33, 22, 5])

三、NumPy

如果想对数组做一些高级数值处理应该使用NumPy库。NumPy实现了多维同构数组和矩阵类型,处理存放数值之外,还可以存放用户定义的记录,而且提供了高效的元素层面操作。

NumPy的数组类被调用N维数组对象ndarray,它是一系列同类型数据的集合,这与python标准库类array中的array不同,array.array只处理一维数组并提供较少的功能。

ndarray对象的重要属性:

ndarray.ndim:数组的轴(维度)的个数;

ndarray.shape:返回一个整数的元组,表示每个维度中数组的大小,shape元组的长度就是维度可数ndim;

ndarray.size:数组元素的总数,等于 shape 各个元素的乘积;

ndarray.dtype:一个描述数组中元素类型的对象;

ndarray.itemsize:数组中每个元素的字节大小。

示例:numpy.ndarray中行和列的基本操作

import numpy as np# arange([start, ]stop[, step]用于生成数组ndarray,值在半开区间[start,stop]内
a = np.arange(12)
print(a)        # output: [ 0  1  2  3  4  5  6  7  8  9 10 11]
print(type(a))      # output: <class 'numpy.ndarray'>
print(a.size)       # output: 12
print(a.shape)      # output: (12,)
print(a.dtype)      # output: int64
print(a.itemsize)       # output: 8
# 改变数组的维度
a.shape = 3, 4
print(a)
# output:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
print(a.ndim)       # output: 2
print(a[:, 1])      # output: [1 5 9]
print(a[2, 1])      # output: 9
# 转置数组
print(a.transpose()) 
# output:
# [[ 0  4  8]
#  [ 1  5  9]
#  [ 2  6 10]
#  [ 3  7 11]]

NumPy还支持一些高级操作,如加载、保存和操作numpy.ndarray对象的所有元素

numpy.savetxt():以简单的文本文件格式(txt文件或csv文件)存储数据;

numpy.loadtxt():基本功能是从文本文件中读取数据,并将其转换为NumPy数组,主要处理如CSV文件或空格分隔的文件,它会自动处理数据的分隔符、数据类型和行结束符,使读取文本数据变得简单;

numpy.save():将数组保存到以.npy为扩展名的文件中,文件中的数据是乱码的,因为是Numpy专用的二进制格式化后的数据;

numpy.savez():将多个数组保存到以.npz为扩展名的文件中;

numpy.load():读取以.npy文件为扩展名的数据。

四、双端队列

借助.append、.pop方法,列表也可以当做栈或队列使用,但是在列表头部插入或删除项有一定开销,因为整个列表必须在内存中移动。collections.deque类实现一种线程安全的双端队列,旨在快速在两端插入和删除项(近似O(1)的性能),但从deque对象中部删除项的速度并不快。

deque对象可以固定长度,在对象被填满后,从一端添加新项,将从另一端丢弃另一项,这是实现保留“最后几项”或类似操作的唯一选择。

示例:展示deque对象可执行的一些典型操作

from collections import deque# maxlen为deque的限制长度
dq = deque(range(10), maxlen=10)
print(dq)       # output: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
# 轮转:num>0,从右端取num项放到左端;num<0,从左端取num项放到右端
dq.rotate(3)
print(dq)       # output: deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6], maxlen=10)
dq.rotate(-4)
print(dq)       # output: deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0], maxlen=10)
# 左端添加元素-1,此时向已满,左端端添加几项,右端就要舍弃几项
dq.appendleft(-1)
print(dq)       # output: deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
# extend(iter)依次将iter中的元素追加到deque右端
dq.extend([11, 22, 33])
print(dq)       # output: deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33], maxlen=10)
# extendleft(iter)依次将iter中的元素追加到deque左端
dq.extendleft([10, 20, 30, 40])
print(dq)       # output: deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8], maxlen=10)

list和deque之间的方法:

deque实现了多数list方法,另外增加了专用方法,如:popleft和rotate。

deque中的append和popleft是原子操作(执行时不会被打断,执行前后系统状态保持一致),因此可以放心的在多线程应用中把deque作为先进先出队列使用,无须加锁。

五、其他队列

除deque外,python标准库中的其他包还实现了以下队列:

1.queue

实现了面向多生产线程、多消费线程的队列。提供了几个同步队列类,可用于构建多线程应用程序:

simpleQueue:无界的先进先出队列构造函数,缺少任务跟踪等高级功能;

Queue:有界的先进先出队列;

LifoQueue:有界的后进先出队列;

PriorityQueue:有界的先级队列,按照级别顺序取出元素,级别低的最先取出。

注:queue提供的有界队列与deque的有界不同,它们不像deque那样为了腾出空间而把项丢弃,而是在队列填满后阻塞插入新项,等待其他线程从队列中取出一项。

2.multiprocessing

实现了面向多生产进程、多消费进程的队列。该模块单独实现了无界的simpleQueue和有界的Queue。

与queue.Queue的区别:

queue.Queue是进程内用的队列,是多线程的

multiprocessing.Queue是跨进程通信队列,是多进程的

3.asyncio

实现了面向多生产协程、多消费协程的队列,提供了Queue、PriorityQueue、LifoQueue和JoinableQueue,API源自queue和multiprocessing模块中的类,但是为管理异步编程任务做了修改。

4.heapq

与前三个模块相比,heapq并没有实现任何队列类,但是提供了一系列函数可把可变序列当作堆队列(小顶堆)或优先级队列使用。

heapq相关函数:

heappush(heap,num):先创建一个空堆,然后将数据一个一个添加到堆中,每添加一个数据后,heap都满足小顶堆的特性;

heapify(array):直接将数据列表调整成一个小顶堆;

heappop(heap):将堆顶的数据出堆,并将堆中剩余的数据构造成新的小顶堆;

nlargest(num,heap):从堆中取出num个元素,从最大的数据开始取,返回一个列表;

nsmallest(num,heap):从堆中取出num个元素,从最小的数据开始取,返回一个列表。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • leetcode + react学习
  • Kafka系列之:Dead Letter Queue死信队列DLQ
  • webrtc学习笔记1
  • 企业选型指南:8款最佳工资管理系统推荐
  • 使用 Vue 2 搭建大屏可视化系统
  • 安全入门day.02
  • 断言的用途
  • asyncio模块学习
  • webrtc学习笔记2
  • Dubbo服务自动Web化之路
  • CPU的功能和基本结构
  • 优思学院|六西格玛实施关键:如何整合定性与定量数据
  • 10-使用sentinel流控
  • 免费Excel数据批量转Word工具
  • Affine Transformations仿射变换
  • Apache Zeppelin在Apache Trafodion上的可视化
  • CSS魔法堂:Absolute Positioning就这个样
  • Elasticsearch 参考指南(升级前重新索引)
  • Laravel 中的一个后期静态绑定
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Mysql5.6主从复制
  • Redis 懒删除(lazy free)简史
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • 从0到1:PostCSS 插件开发最佳实践
  • 工程优化暨babel升级小记
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 猴子数据域名防封接口降低小说被封的风险
  • 前嗅ForeSpider教程:创建模板
  • 区块链共识机制优缺点对比都是什么
  • 学习笔记TF060:图像语音结合,看图说话
  • 用element的upload组件实现多图片上传和压缩
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 在Docker Swarm上部署Apache Storm:第1部分
  • Linux权限管理(week1_day5)--技术流ken
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 移动端高清、多屏适配方案
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​渐进式Web应用PWA的未来
  • #include<初见C语言之指针(5)>
  • #java学习笔记(面向对象)----(未完结)
  • #大学#套接字
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (02)Unity使用在线AI大模型(调用Python)
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (5)STL算法之复制
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十八)Flink CEP 详解
  • (四)Android布局类型(线性布局LinearLayout)
  • .bat批处理出现中文乱码的情况
  • .equals()到底是什么意思?
  • .net framework 4.8 开发windows系统服务