数据类型
13.1 数据类型
bisect 使用二分法在一个 "已排序序列" 中查找合适的插入位置
>>> import bisect
>>> b = [20, 34, 35, 65, 78]
>>> bisect.bisect(b, 25) # 查找25在列表中合适的位置。索引 1
1
>>> bisect.bisect_left(b, 35) # 如果待查找元素在列表中存在,则返回左侧插入入位置。
2
>>> bisect.bisect_right(b, 35) # 如果待查找元素在列表中存在,则返回右侧插入入位置。
3
使用bisect.insort_left() 直接插入元素而非查找
>>> bisect.insort
bisect.insort( bisect.insort_left( bisect.insort_right(
>>> bisect.insort_left(b,25)
>>> b
[20, 25, 34, 35, 65, 78]
使用bisect 实现一个SortedList
>>>
>>> def sorted_list(list, *elements):
... for e in elements:
... bisect.insort_right(list, e)
... return list
...
>>> sorted_list([], 3,4,7,1)
[1, 3, 4, 7]
13.2 heapq
最小堆:完全平衡二叉树,所有节点都小于字节点。
堆的意义:最快找到最大/最小值。在堆结构中插入或删除最小(最大)元素时进行重新构造时间复杂度为O(logN),而其他方法最少为O(N)。堆在实际开发中的更倾向于算法调度而非排序。比如优先
级调度时,每次取优先级最高的;时间驱动调度时,取时间最小或等待最长的等等。
>>> from heapq import *
>>> from random import *
>>> rand = sample(range(1000), 10) # 生成随机数
>>> rand
[852, 3, 98, 10, 331, 716, 84, 717, 366, 952]
>>>
>>> heap = []
>>> for x in rand: heappush(heap,x) # 将随机数压入堆
...
>>> heap # 堆是树,并非非排序列表。
[3, 10, 84, 366, 331, 716, 98, 852, 717, 952]
>>> while heap: print(heappop(heap)) # 总是弹出最小元素
...
3
10
84
...
heapq函数
heap =[]
heappush(heap, x): 将x压入堆
heappop(heap): 总是弹出最小元素
heapify(list): 将列表转换堆
heappushpop(list, -1): 先 push(item),后 pop。弹出值肯定小小于或等于 item
heapreplace(list, -1) : 先 pop,后 push(item)。弹出值可能大大于 item。
merge(a, b): 合并有序序列
nlargest(n, list) : 从列表有序返回最大的n个元素
nsamllest(n, list): 返回最小
>>> d = sample(range(10), 10)
>>> d
[4, 5, 9, 2, 7, 8, 3, 6, 1, 0]
>>> heapify(d) # 将列表转换为堆
>>> d
[0, 1, 3, 2, 5, 8, 9, 6, 4, 7]
>>> heappushpop(d,-1) # 先 push(item),后 pop。弹出值肯定小小于或等于 item。
-1
>>> heapreplace(d, -1) # 先 pop,后 push(item)。弹出值可能大大于 item
0
>>> a = range(1, 10, 2)
>>> b = range(2, 10, 2)
>>> [x for x in merge(a,b)] # 合并有序序列
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ls = sample(range(20), 10)
>>> ls
[14, 16, 6, 2, 4, 19, 0, 12, 10, 8]
>>> nlargest(5, ls) # 有序返回最大的n个元素
[19, 16, 14, 12, 10]
>>> nsmallest(5, ls)
[0, 2, 4, 6, 8]
利用元组__cmp__, 用数字表示对象优先级,实现优先级队列
from string import ascii_letters
from heapq import *
from random import *
>>> data = list(zip(sample(range(100), 10), sample(ascii_letters, 10)))
>>> heap = []
>>> for item in data: heappush(heap, item)
...
>>> heap
[(5, 'E'), (16, 'Z'), (29, 'I'), (42, 'x'), (43, 'm'), (54, 'z'), (67, 'g'), (53, 'Q'), (66, 'A'), (63, 'y')]
>>>
>>> while heap: print(heappop(heap))
...
(5, 'E')
(16, 'Z')
(29, 'I')
(42, 'x')
(43, 'm')
(53, 'Q')
(54, 'z')
(63, 'y')
(66, 'A')
(67, 'g')
数学运算
14.1 random
伪随机数生成模块, 如果不提供seed, 默认使用系统时间。
使用相同seed, 可获得相同哦你的随机数序列,用于测试
>>> from random import *
>>> a = Random();a.seed(1)
>>> [a.randint(1,100) for i in range(20)]
[18, 73, 98, 9, 33, 16, 64, 98, 58, 61, 84, 49, 27, 13, 63, 4, 50, 56, 78, 98]
>>> b = Random();b.seed(1)
>>> [b.randint(1,100) for i in range(20)]
[18, 73, 98, 9, 33, 16, 64, 98, 58, 61, 84, 49, 27, 13, 63, 4, 50, 56, 78, 98]
生成最大N 个二进制位的长整数
>>> getrandbits(5)
25
>>> bin(getrandbits(5))
'0b11000'
生成 start <= N < stop 范围内的随机整数
>>> randrange(1,3)
2
>>> randrange(1,3,2)
1
>>> randrange(1,3,2)
1
生成 a <= N <= b 范围内的整数
>>> randint(1,3)
3
从序列中随机返回1元素
>>> choice(string.digits)
'1'
>>> choice([1,4,5])
5
打乱序列,随机洗牌
>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> shuffle(a)
>>> a
[3, 5, 8, 9, 0, 1, 2, 6, 4, 7]
从序列中随机挑选n个元素
>>> import string
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> ''.join(sample(string.ascii_letters, 10))
'QNDSztLbor'
生成 0.0 <= N < 1 的随机浮点数
>>> random()
0.20589315926872043
生成 min <= N <= max 范围内的随机浮点数
>>> uniform(1, 10)
7.873857408006966
random模块函数:
getrandbits(5) 生成最大 N 个二进制位的长整数
randrange(n, m) [n, m) 中的随机整数
randint(n, m) [n, m] 随机整数
choice(s) 序列中随机取一个数
shuffle(s) 打乱序列,重新洗牌
sample(s, n) 从序列中随机选取n个
random() [0, 1) 随机浮点数
uniform(n, m) [n, m] 随机浮点数