对于百万级以上数据的读写效率优化
在Python中,我们可以通过array模块来方便地创建和操作数组,array模块提供了性能优异的数组操作方法,可以使我们的代码更加高效。同时,Python也提供了读写二进制文件和普通文本文件的方法,对于一些需要处理大量数据
的程序,我们可以通过比较二者的性能来选择更加高效的操作方式。
读写二进制文件和普通文本文件的性能对比:
from array import array
import os
from time import time# 生成测试数据
a = array('i', range(1000000))# 测试 array.fromfile() 和 array.tofile()
t1 = time()
with open('test.bin', 'wb') as f:a.tofile(f)
with open('test.bin', 'rb') as f:b = array('i')b.fromfile(f, len(a))
t2 = time()
print(f"array.fromfile() and array.tofile(): {t2-t1:.6f} seconds")
os.remove('test.bin')# 测试普通文本文件读写
t3 = time()
with open('test.txt', 'w') as f:for i in a:f.write(str(i) + '\n')
with open('test.txt', 'r') as f:b = []for line in f:try:b.append(int(line.strip()))except ValueError:pass
t4 = time()
print(f"Text file read and write: {t4-t3:.6f} seconds")
运行上述代码会得到以下结果
array.fromfile() and array.tofile(): 0.021007 seconds Text file read and write: 7.798990 seconds
我们可以发现,在处理大量数据时,二进制文件读写的性能要远远优于普通文本文件读写。这是因为,在使用普通文本文件进行读写时,需要将每个元素转换成字符串并添加换行符,这些额外的操作会影响程序的性能
快速在有序序列中插入一个元素,并保持有序性
import bisectmy_list = [1, 3, 4, 7, 8, 10]
bisect.insort(my_list, 6)
print(my_list)
bisect.insort
使用二分查找算法来查找元素应该插入的位置,然后使用list.insert()
方法将元素插入到该位置。这个函数的时间复杂度为O(log n)
,其中n是序列的长度。
bisect.insort()函数的实现方式与bisect.bisect()函数类似。bisect.bisect()
函数返回元素应该插入的位置,而bisect.insort()函数则将元素插入到该位置
使用双向队列
collections.deque
类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。而且如果想要有一种数据类型来存放“最近用到的几个元素”,deque也是一个很好的选择。这是因为在新建一个双向队列的时候,你可以指定这个队列的大小,如果这个队列满员了,还可以从反向端删除过期的元素,然后在尾端添加新的元素
以下介绍两个使用双向队列的小案例:
- 实现一个滑动窗口
双向队列可以用于实现一个滑动窗口,该窗口可以在O(k)的时间复杂度内在一个序列中滑动,其中k是窗口的大小。以下是一个简单的示例:
from collections import dequedef sliding_window(nums, k):# 在序列nums中实现一个大小为k的滑动窗口result = []window = deque()for i, num in enumerate(nums):if i >= k and window[0] <= i - k:window.popleft()while window and nums[window[-1]] >= num:window.pop()window.append(i)if i >= k - 1:result.append(nums[window[0]])return result
在这个示例中,sliding_window()函数使用双向队列实现了一个大小为k的滑动窗口。该函数首先创建一个空的双向队列window,然后遍历序列nums中的每个元素。在每个元素上,该函数执行以下操作:
- 如果队列中的第一个元素已经超出了窗口的范围,则将其从队列中删除。
- 如果队列中的最后一个元素大于等于当前元素,则将其从队列中删除,直到队列为空或者最后一个元素小于当前元素。
- 将当前元素的下标添加到队列的末尾。
- 如果当前元素的下标大于等于k-1,则将队列中的第一个元素添加到结果列表中。
这个函数的时间复杂度为O(n)
,其中n是序列的长度。
- 实现一个循环队列
双向队列可以用于实现一个循环队列,该队列可以在O(1)的时间复杂度内在队列两端进行插入和删除操作。以下是一个简单的示例:
from collections import dequeclass CircularQueue:# 初始化一个大小为k的循环队列def __init__(self, k):self.k = kself.queue = deque(maxlen=k)# 将一个元素插入到队列的尾部。如果队列已满,则返回Falsedef enQueue(self, value):if len(self.queue) < self.k:self.queue.append(value)return Trueelse:return False# 将队列的头部元素删除。如果队列为空,则返回Falsedef deQueue(self):if self.queue:self.queue.popleft()return Trueelse:return False# 返回队列的头部元素。如果队列为空,则返回-1def Front(self):return self.queue[0] if self.queue else -1# 返回队列的尾部元素。如果队列为空,则返回-1def Rear(self):return self.queue[-1] if self.queue else -1
这个类的时间复杂度为O(1)
。
如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!
😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓
Python全套学习资料
1️⃣零基础入门
① 学习路线
对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
② 路线对应学习视频
还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
③练习题
每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
2️⃣国内外Python书籍、文档
① 文档和书籍资料
3️⃣Python工具包+项目源码合集
①Python工具包
学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
②Python实战案例
光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
③Python小游戏源码
如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
4️⃣Python面试题
我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
5️⃣Python兼职渠道
而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓