流畅的pyton 2.8 bisect(note)
In [12]:
import bisect
HAYSTACK = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
NEEDLES = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]
fmt = '{0:2d} @ {1:2d} {2}{0:<2d}'
def Demo(bisect_fn):
for needle in reversed(NEEDLES): #必须先排序,反向在这里方便显示
position = bisect_fn(HAYSTACK,needle)
offset = position * ' |'
print(fmt.format(needle,position,offset))
print("HAYSTACK <- "," ".join('%2d' % n for n in HAYSTACK))
Demo(bisect.bisect_left)
Output:
HAYSTACK <- 1 4 5 6 8 12 15 20 21 23 23 26 29 30
31 @ 14 | | | | | | | | | | | | | |31
30 @ 13 | | | | | | | | | | | | |30
29 @ 12 | | | | | | | | | | | |29
23 @ 9 | | | | | | | | |23
22 @ 9 | | | | | | | | |22
10 @ 5 | | | | |10
8 @ 4 | | | |8
5 @ 2 | |5
2 @ 1 |2
1 @ 0 1
0 @ 0 0
In [13]:
print("HAYSTACK <- "," ".join('%2d' % n for n in HAYSTACK))
Demo(bisect.bisect)
Output:
HAYSTACK <- 1 4 5 6 8 12 15 20 21 23 23 26 29 30
31 @ 14 | | | | | | | | | | | | | |31
30 @ 14 | | | | | | | | | | | | | |30
29 @ 13 | | | | | | | | | | | | |29
23 @ 11 | | | | | | | | | | |23
22 @ 9 | | | | | | | | |22
10 @ 5 | | | | |10
8 @ 5 | | | | |8
5 @ 3 | | |5
2 @ 1 |2
1 @ 1 |1
0 @ 0 0
In [16]:
#根据一个分数,确定到它所对应的成绩ABCDF
def grade(score,break_point=[60,70,80,90],grades='FDCBA'):
i = bisect.bisect(break_point,score)
return grades[i]
[ grade(n) for n in [33, 99, 77, 70, 89, 90, 100]]
Output:
Out[16]:
['F', 'A', 'C', 'C', 'B', 'A', 'A']
In [19]:
#bisect.insort 可以保持有序序列的顺序
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)
Output:
10 -> [10]
0 -> [0, 10]
6 -> [0, 6, 10]
8 -> [0, 6, 8, 10]
7 -> [0, 6, 7, 8, 10]
2 -> [0, 2, 6, 7, 8, 10]
10 -> [0, 2, 6, 7, 8, 10, 10]
In [24]:
#insort_left
import random
SIZE=7
random.seed(1729)
my_list=[]
for i in range(SIZE):
new_item = random.randrange(SIZE*2)
bisect.insort_left(my_list,new_item)
print('%2d -> ' % new_item, my_list)
Output:
10 -> [10]
0 -> [0, 10]
6 -> [0, 6, 10]
8 -> [0, 6, 8, 10]
7 -> [0, 6, 7, 8, 10]
2 -> [0, 2, 6, 7, 8, 10]
10 -> [0, 2, 6, 7, 8, 10, 10]
In [30]:
#一个小试验告诉我,用array.fromfile 从一个二
#进制文件里读出1000 万个双精度浮点数只需要0.1 秒,这比从文本文件里读取的速度要快
#60 倍,因为后者会使用内置的float 方法把每一行文字转换成浮点数。另外,使用array.
#tofile 写入到二进制文件,比以每行一个浮点数的方式把所有数字写入到文本文件要快7
#倍。另外,1000 万个这样的数在二进制文件里只占用80 000 000 个字节(每个浮点数占用
#8 个字节,不需要任何额外空间),如果是文本文件的话,我们需要181 515 739 个字节。
from array import array
from random import random
floats = array('d',(random() for i in range(10**7))) #使用了生成器表达式
print(floats[-1])
fp = open('floats.bin','wb')
floats.tofile(fp)
fp.close()
Output:
0.5963321947530882
In [39]:
floats2 = array('d')
fp2 = open('floats.bin','rb')
floats2.fromfile(fp2,10**7)
fp2.close()
print(floats2[-1])
Output:
0.5963321947530882
In [41]:
# 列表 数组
#s.__add(s2)__ • • s + s2 ,拼接
#s.__iadd(s2)__ • • s += s2 ,就地拼接
#s.append(e) • • 在尾部添加一个元素
#s.byteswap • 翻转数组内每个元素的字节序列,转换字节序
#s.clear() • 删除所有元素
#s.__contains__(e) • • s 是否含有e
#s.copy() • 对列表浅复制
#s.__copy__() • 对copy.copy 的支持
#s.count(e) • • s 中e 出现的次数
#s.__deepcopy__() • 对copy.deepcopy 的支持
#s.__delitem__(p) • • 删除位置p 的元素
#s.extend(it) • • 将可迭代对象it 里的元素添加到尾部
#s.frombytes(b) • 将压缩成机器值的字节序列读出来添加到尾部
#s.fromfile(f, n) • 将二进制文件f 内含有机器值读出来添加到尾部,最多添加n 项
#s.fromlist(l) • 将列表里的元素添加到尾部,如果其中任何一个元素导致了TypeError 异常,那么所有的添加都会取消
#s.__getitem__(p) • • s[p],读取位置p 的元素
#s.index(e) • • 找到e 在序列中第一次出现的位置
#s.insert(p, e) • • 在位于p 的元素之前插入元素e
#s.itemsize • 数组中每个元素的长度是几个字节
#s.__iter__() • • 返回迭代器
#s.__len__() • • len(s),序列的长度
#s.__mul__(n) • • s * n,重复拼接
#s.__imul__(n) • • s *= n ,就地重复拼接
#s.__rmul__(n) • • n * s ,反向重复拼接*
#s.pop([p]) • • 删除位于p 的值并返回这个值,p 的默认值是最后一个元素的位置
#s.remove(e) • • 删除序列里第一次出现的e 元素
#s.reverse() • • 就地调转序列中元素的位置
#s.__reversed__() • 返回一个从尾部开始扫描元素的迭代器
#s.__setitem__(p, e) • • s[p] = e,把位