对于一个有序队列进行查找和插入,最好的方法是二分查找算法。在python的bisect模块就提供了这样的功能,bisect.bisect(a, x, lo=0, hi=len(a))提供了查找插入位置,bisect.insort(a, x, lo=0, hi=len(a))提供了插入元素到列表。
import bisect
s = [60,70,80,90]
g = 'FDCBA'
i = bisect.bisect(s,85)
print(g[i])
在这里通过bisect.bisect函数找到分数有序列表s,然后判断分数85分属于那一段位置,拿到索引之后再通过g级别进行映射输出,就拿到分数转换为字母的分数分级了。
二分插入排序
import bisect
import random
SIZE = 7
random.seed(1729)
my_list = []
for i in range(SIZE):
new_item = random.randrange(SIZE*2)
bisect.insort(my_list, new_item)
print('%2d ->' % new_item, my_list)
这段代码演示了二分插入排序的情况和使用。
bisect.insort和bisect.insort_left的区别是:当插入元素与列表里的元素相等时,插入元素在后面,而后者把元素插入在相等元素的左边。
什么时候不使用列表?
列表虽然比较灵活,也功能强大,但是它也是有缺点的。比如保存100万个浮点数时,它就没有比array.array有效率,比如内存占用大,保存磁盘也大,加载时间更长。
import array
import random
floats = array.array('d', (random.random() for i in range(10**7)))
print(floats[-1])
fp = open('f1.bin','wb')
floats.tofile(fp)
fp.close()
floats2 = array.array('d')
fp = open('f1.bin','rb')
floats2.fromfile(fp, 10**7)
fp.close()
print(floats2[-1])
print(floats == floats2)
通过这个例子,可以看到array.array保存10000000个双精度浮点数,需要的时间很少,文件才76M左右大小。如果使用列表会比较慢,你们可以尝试一下。
memoryview
当大量处理字节类型的数据时,为了提高性能,不能动不动就拷贝数据,这时python提供了共享内存的类memoryview。
使用memoryview进行类型转换
import array
import random
n = array.array('h', [-2, -1, 0, 1, 2])
m = memoryview(n)
print(len(m))
print(m[0])
m1 = m.cast('B')
print(m1.tolist())
在这里创建一个array.array有符号的16位数组,然后创建memoryview对象m,接着使用.cast('B')转换无符号char数组,再进行输出:
5
-2
[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]
如果大量处理数学类型数据,需要使用numpy和scipy。
deque
在处理栈或者队列时,就可以使用双端队列。
from collections import deque
dq = deque(range(10),maxlen = 10)
print(dq)
dq.rotate(3)
print(dq)
dq.appendleft(-10)
print(dq)
dq.extend([20,30,40])
print(dq)
在这里演示了使用限长队列,可以进行元素增加或翻转。
还有其库提供队列:queue提供线程安全的队列,multiprocessing提供多线性交互队列,asyncio提供作务管理队列,heapq提供堆操作队列。
玩转人工智能库-深入浅出OpenCV
https://edu.csdn.net/course/detail/26616