zoukankan      html  css  js  c++  java
  • list.sort和sorted以及bisect

    # list.sort方法和内置函数sorted
    
    # list.sort方法会就地排序列表,也就是说不会把原列表复制一份.这也是这个方法的返回值是None的原因,提醒你本方法不会新建一个列表.
    # 在这种情况下返回None其实是Python的一个惯例: 如果一个函数或者方法对对象进行的是就地改动,那么它就应该返回None,好让调用者知道传入的参数发生了变动,并且并未产生新的对象.
    
    # 与list.sort相反的是内置函数sorted(),它会新建一个列表作为返回值.这个方法可以接受任何形式的可迭代对象作为参数,甚至包括不可变序列或生成器.
    # 而不管sorted接受的是怎样的参数,它最后都会返回一个列表.
    
    # 不管是list.sort还是sorted函数,都有两个可选的关键字参数
    # reverse: 如果被设定为True,被排序的序列里的元素会以降序输出,这个参数的默认值是False
    # key: 一个只有一个参数的函数,这个函数会被用在序列里的每一个元素上,所产生的结果将是排序算法依赖的对比关键字.
    #   比如说,在对一些字符串排序时,可以用key=str.lower来实现忽略大小写的排序,或者用key=len进行基于字符串长度的排序
    #   这个参数的默认值是恒等函数,也就是默认用元素自己的值来排序.
    
    # 下面通过几个小例子来看看这两个函数和它们的关键字参数
    fruits = ["grape", "raspberry", "apple", "banana"]
    print(sorted(fruits))  # 新建了一个按照字母排序的字符串列表
    print(fruits)  # 原列表没有变化
    print(sorted(fruits, reverse=True))  # 按照字母降序排列
    print(sorted(fruits, key=len))  # 新建一个按照长度排序的字符串列表.因为这个排序算法是稳定的,grape和apple的长度都是5,它们的相对位置跟在原来的列表里是一样的.
    print(sorted(fruits, key=len, reverse=True))  # 按照长度降序排列,结果并不上上面那个结果的完全翻转,因为用到的排序算法是稳定的,也就是说在长度一样时,grape和apple的相对位置不会改变.
    print(fruits.sort())  # 对原列表进行就地排序,返回值是None
    print(fruits)  # 此时fruits本身被排序
    
    # 已排序的序列可以用来进行快速搜索,而标准库的bisect模块给我们提供了二分查找法.
    # 用bisect来管理已排序的序列 bisect模块包含两个主要函数,bisect和insort,两个函数都利用二分查找法来在有序序列中查找和插入元素
    # bisect(haystack, needle)在haystack里搜索needle的位置,该位置满足的条件是,把needle插入这个位置后,haystack还能保持升序.
    # 也就是说这个函数返回的位置前面的值,都小于或等于needle的值.
    # 可以使用bisect(haystack, needle)来查找位置index,再用haystack.insert(index, needle)来插入新值.但是也可以用insort来一步到位,并且后者的速度会快一点.
    
    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}"
    
    
    def demo(bisect_fn_):
        for needle in reversed(NEEDLES):
            position = bisect_fn_(HAYSTACK, needle)  # 用特定的bisect函数来计算元素应该出现的位置
            offset = position * "   |"  # 利用该位置计算出需要几个分割符号
            print(ROW_FMT.format(needle, position, offset))  # 把元素和其应该出现的位置打印出来
    
    
    def grade(score, breakpoints=None, grades='FDCBA'):
        # 讲分数与评级对应起来 60以下F,90以上A
        breakpoints = [60, 70, 80, 90] if not breakpoints else breakpoints
        i = bisect.bisect(breakpoints, score)
        return grades[i]
    
    
    # 用bisect.insort插入新的元素
    # 排序很耗时,因此在得到一个有序序列之后,我们最好能够保持它的有序.bisect.insort就是为了这个而存在的
    # insort(seq, item)把变量item插入到序列seq中,并能保持seq的升序顺序.
    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)
        """
        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]
        """
    
    
    if __name__ == '__main__':
        if sys.argv[-1] == 'left':  # 根据命令行上最后一个参数来选用bisect函数
            bisect_fn = bisect.bisect_left
        else:
            bisect_fn = bisect.bisect
    
        print('DEMO:', bisect_fn.__name__)  # 把选定的函数在抬头打印出来
        print('haystack ->', '  '.join('%2d' % n for n in HAYSTACK))
        demo(bisect_fn)
        """
        DEMO: bisect
        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 
        """
        print([grade(score) for score in [33, 99, 77, 70, 89, 90, 100]])
    
    
  • 相关阅读:
    Notes of Daily Scrum Meeting(12.18)
    Notes of Daily Scrum Meeting(12.17)
    Notes of Daily Scrum Meeting(12.16)
    Notes of Daily Scrum Meeting(12.8)
    Notes of Daily Scrum Meeting(12.5)
    Notes of Daily Scrum Meeting(12.3)
    Notes of Daily Scrum Meeting(11.12)
    Linux中profile、bashrc、bash_profile之间的区别和联系
    Linux GCC编译
    mysql 5.7.16 远程连接
  • 原文地址:https://www.cnblogs.com/zyyhxbs/p/13143883.html
Copyright © 2011-2022 走看看