2.8用bisect来管理已排序的序列

参考资料:Luciano Ramalho《流畅的python》

1、bisect模块里的bisect函数

bisect(arg1,arg2)
arg1:参数haystack,是一个【按升序排列】的iterable,这里本例中是一个list
haystack/'heɪstæk/n. 大干草堆
arg2:参数needle,与参数1那个iterable中的element类型相同
返回值:返回一个数字,这个数字是索引
其实bisect函数 == bisect_right函数
它还有个姊妹函数 bisect_left
不管是哪个函数,它的返回值都满足,将needle插入到对应的index后,haystack仍然可以保持升序
但是,如果needle与haystack中的某个element相等时
bisect函数把它插入到原有元素的右边
bisect_left函数把它插入到原有元素的左边

2、字符串格式规约

字符换格式规约使用冒号(:)引入,其后跟随可选的字符对
1、填充字符(可以没有)
2、对齐字符(^<>),
3、最小宽度(int),
4、最大宽度(.int)
注意:制定了填充字符,就必须同时指定对齐字符

print('{:^100}'.format('陈某某'))
# ^ 表示居中,100表示宽度,即在100个字符的长度内,把打印内容置于中间,(打印内容加上左右空出的部分,共100个字符)
print('{:>14}'.format('陈某某'))  # > 表示右对齐
print('{:<14}'.format('陈某某'))  # < 表示左对齐
print('{:*<14}'.format('陈某某'))  # 空出的部分用*来填充,*加上其它内容,共14个字符
print('{:&>14}'.format('陈某某'))  # 空出的部分用来填充,*加上其它内容,共14个字符
打印结果是:
                                                陈某某
           陈某某
陈某某
陈某某***********
&&&&&&&&&&&陈某某

3、join方法

join方法
str.join(sequence)
sequence大致是一种可迭代对象

print('*'.join('builtins'))  # b*u*i*l*t*i*n*s
print('*'.join(['小刚', '小明', '小红', '小亮']))  # 小刚*小明*小红*小亮

4、用bisect来搜索

import bisect
import sys

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]
ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'


# 空白处分别是一个空格,一个空格,四个空格
# ROW_FMT就是row_format,即格式化的行
# 【第一个参数】对应字段名{0:2d}和{0:<2d}
# : 用于引入【字符换格式规约】
# {0:2d}2表示最小宽度是2,d即digital,类型是数字
# {0:<2d}小于号表示左对齐,2表示最小宽度是2,d即digital,类型是数字

def demo(bisect_fn):
    for needle in reversed(NEEDLES):
        # 这个,为什么要把NEEDLES颠倒一下?我认为,为了打印出来好看
        position = bisect_fn(HAYSTACK, needle)
        offset = position * '  |'
        print(ROW_FMT.format(needle, position, offset))
        # position是needle在HAYSTACK中应有的索引
        # offset大概是缩进
        # 下面是格式化的行needle @ 索引    缩进  needle
        # 这个格式的意义:索引多少就缩进多少


if __name__ == '__main__':
    if sys.argv[-1] == 'left':
        bisect_fn = bisect.bisect_left
    else:
        bisect_fn = bisect.bisect
    # 如果外界向此文件传入参数left,那么我们取bisect_fn为bisect_left
    # 无特殊要求就是bisect
    # 这两个姊妹函数的细微差别可能对于整数序列来说没有什么用,但是对于那些值相等但是形式不同的数据类型来说,
    # 结果就不一样了。
    print('DEMO:', bisect_fn.__name__)
    print('haystack ->', ' '.join('%2d' % n for n in HAYSTACK))
    demo(bisect_fn)
    # 先打印  DEMO: bisect_right
    # 此处,print(bisect.bisect.__name__)  # bisect_right
    # 接下来是haystack ->
    # print(len('haystack ->'))  # 11
    # 下面是格式化的行里的{2}之前的表达式({0:2d} @ {1:2d}    )
    # 它的宽度 == 2 + 1 + 1 + 1 + 2 + 4 == 11 == len('haystack ->')
    # 这样表格的左边就对齐了
    # 接下来一个offset占位 == index * 3
    # 而对于
    # print('haystack ->', ' '.join('%2d' % n for n in HAYSTACK))
    # 来说,% 格式化字符串默认右对齐,最小宽度是2,又在间隙里加上了一个空格
    # 相当于除了第一个数字外,每一个数字占三个格
    # 又因为中间的“,”,打印出来会占一个格,所以每个数字都占三个格。
    #打印结果:
    # DEMO: bisect_right
	# 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 

猜你喜欢

转载自blog.csdn.net/xi_yang_hui/article/details/83115873