• 流畅的Python---list排序和保持有序序列


    1. 列表 使用 list.sort方法 和内置函数 sorted 排序

      不管是list.sort还是sorted函数,list.sort会就地排序列表,不会把列表复制一份,sorted会产生新的对象,有两个可选关键参数:reverse 和 key。

        reverse:ture为降序。默认为false,为升序。

        key:  排序算法依赖的对比关键字。比如:key=str.lower 实现忽略大小写的排序 , key=len 实现字符串长度的排序,默认的是恒等函数,也就是默认使用元素的值排序。

    # 水果list
    fruits = ['grape', 'raspberry', 'apple', 'banana']
    # 获取对象内存地址
    print(id(fruits))
    # 使用list.sort默认排序
    fruits.sort()
    # 查看效果
    print(fruits)
    # 使用内置sorted函数默认排序
    print(sorted(fruits))
    # 获取对象内存地址
    print(id(fruits))
    # 获取对象内存地址
    print(id(sorted(fruits)))
    
    # 结果
    # 1597512311304
    # ['apple', 'banana', 'grape', 'raspberry']
    # ['apple', 'banana', 'grape', 'raspberry']
    # 1597512311304
    # 1597512311368
    

      list.sort(key= ,reverse = ) 与sorted(list, key = , reverse = )等可选参数的排序,可自行尝试结果。

    2. 使用bisect 保持已排序列

      bisect是一个模块,这个模块中主要包括两个函数:bisect 和 insort 。这两个函数都是使用二分查找算法对有序序列中查找或插入元素。

      注意:必须是已经排好序的有序序列。

      模块bisect中bisect函数:bisect(有序序列L,想搜索的值x),返回x可以插入L中的index,(所以说,如果是升序的情况下,返回的index前边的值都是小于或等于x的值),index是有序序列中的索引。

                 找到index后再使用L.insert(index,想搜索的值x)插入新值x。

      我们也可以使用模块bisect中insort函数一步到位。

    # 引入bisect模块
    import bisect
    # import sys
    
    # 制作一有序序列 HAYSTACK
    HAYSTACK = [1, 4, 5, 6, 8, 12, 15, 20, 21, 23, 23, 26, 29, 30]
    # 想要插入HAYSTACK中的值
    NEEDLES = [0, 1, 2, 5, 8, 10, 22, 23, 29, 30, 31]
    # 打印输出,format用法 ,2d补足宽度为2
    ROW_FMT = '{0:2d} @ {1:2d}    {2}{0:<2d}'
    # 写一个demo函数打印效果
    def demo(bisect_fn):
        # 将需要插入的数 一个一个的遍历
        for needle in reversed(NEEDLES):
            # 返回可插入的位置
            position = bisect_fn(HAYSTACK, needle)
            # 位置数从1开始,所以打印将前方的数都置为 |
            offset = position * '  |'
            # 填充数据
            print(ROW_FMT.format(needle, position, offset))
    
    if __name__ == '__main__':
        bisect_fn = bisect.bisect
        print('DEMO:', bisect_fn.__name__)
        print('haystack ->', ' '.join('%2d' % n for n in HAYSTACK))
        demo(bisect_fn) 
    
    # 结果
    # 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 
    

      可通过bisect中两个可选参数:lo和hi 缩小收缩范围

      这种使用方式在很多地方都使用的上,例如:一个人的各科成绩要转换成对应的 成绩 等级,4行代码解决问题

    def grade(score,breakpoints=[60, 70, 80, 90],grades='FDCBA'):
        i = bisect.bisect(breakpoints, score)
        return grades[i]
    print([grade(score) for score in [33, 99 ,77 ,70 , 89, 90, 100]])
    # 结果
    # ['F', 'A', 'C', 'C', 'B', 'A', 'A']
    

      用bisect.insort插入新元素

    import bisect
    import random
    
    SIZE = 7
    # seed改变随机数生成器的种子,使每次结果相同
    random.seed(1729)
    my_list = []
    for i in range(SIZE):
        # 0到SIZE*2选取一个随机数
        new_item = random.randrange(SIZE*2)
        bisect.insort(my_list, new_item)
        print('%2d ->' % new_item,my_list)
    # 结果    
    # 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]
    

     

      

  • 相关阅读:
    NSIS 2.0界面快速入门
    [反汇编练习] 160个CrackMe之016
    [反汇编练习] 160个CrackMe之015
    [反汇编练习] 160个CrackMe之014
    [反汇编练习] 160个CrackMe之013
    Ubuntu 安装之python开发
    git 技能图
    linux 系统 权限
    Git 常用命令
    python 之virtualenv和virtualenvwrapper使用
  • 原文地址:https://www.cnblogs.com/coylee/p/10744226.html
Copyright © 2020-2023  润新知