zoukankan      html  css  js  c++  java
  • Bisect in Python

    bisect — Array bisection algorithm

    This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with expensive comparison operations, this can be an improvement over the more common approach. The module is called bisect because it uses a basic bisection algorithm to do its work. The source code may be most useful as a working example of the algorithm (the boundary conditions are already right!).

    The following functions are provided:

    bisect.bisect_left(axlo=0hi=len(a))

    Locate the insertion point for x in a to maintain sorted order. The parameters lo and hi may be used to specify a subset of the list which should be considered; by default the entire list is used. If x is already present in a, the insertion point will be before (to the left of) any existing entries. The return value is suitable for use as the first parameter to list.insert() assuming that a is already sorted.

    The returned insertion point i partitions the array a into two halves so that all(val for val in a[lo:i]) for the left side and all(val >= for val in a[i:hi]) for the right side.

    bisect.bisect_right(axlo=0hi=len(a))
    bisect.bisect(axlo=0hi=len(a))

    Similar to bisect_left(), but returns an insertion point which comes after (to the right of) any existing entries of x in a.

    The returned insertion point i partitions the array a into two halves so that all(val <= for val in a[lo:i]) for the left side and all(val for val in a[i:hi]) for the right side.

    bisect.insort_left(axlo=0hi=len(a))

    Insert x in a in sorted order. This is equivalent to a.insert(bisect.bisect_left(a, x, lo, hi), x) assuming that a is already sorted. Keep in mind that the O(log n) search is dominated by the slow O(n) insertion step.

    bisect.insort_right(axlo=0hi=len(a))
    bisect.insort(axlo=0hi=len(a))

    Similar to insort_left(), but inserting x in a after any existing entries of x.

    source code:

    """Bisection algorithms."""
    
    def insort_right(a, x, lo=0, hi=None):
        """Insert item x in list a, and keep it sorted assuming a is sorted.
        If x is already in a, insert it to the right of the rightmost x.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        lo = bisect_right(a, x, lo, hi)
        a.insert(lo, x)
    
    def bisect_right(a, x, lo=0, hi=None):
        """Return the index where to insert item x in list a, assuming a is sorted.
        The return value i is such that all e in a[:i] have e <= x, and all e in
        a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
        insert just after the rightmost x already there.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        if lo < 0:
            raise ValueError('lo must be non-negative')
        if hi is None:
            hi = len(a)
        while lo < hi:
            mid = (lo+hi)//2
            # Use __lt__ to match the logic in list.sort() and in heapq
            if x < a[mid]: hi = mid
            else: lo = mid+1
        return lo
    
    def insort_left(a, x, lo=0, hi=None):
        """Insert item x in list a, and keep it sorted assuming a is sorted.
        If x is already in a, insert it to the left of the leftmost x.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        lo = bisect_left(a, x, lo, hi)
        a.insert(lo, x)
    
    
    def bisect_left(a, x, lo=0, hi=None):
        """Return the index where to insert item x in list a, assuming a is sorted.
        The return value i is such that all e in a[:i] have e < x, and all e in
        a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
        insert just before the leftmost x already there.
        Optional args lo (default 0) and hi (default len(a)) bound the
        slice of a to be searched.
        """
    
        if lo < 0:
            raise ValueError('lo must be non-negative')
        if hi is None:
            hi = len(a)
        while lo < hi:
            mid = (lo+hi)//2
            # Use __lt__ to match the logic in list.sort() and in heapq
            if a[mid] < x: lo = mid+1
            else: hi = mid
        return lo
    
    # Overwrite above definitions with a fast C implementation
    try:
        from _bisect import *
    except ImportError:
        pass
    
    # Create aliases
    bisect = bisect_right
    insort = insort_right

    examples:

    # Python code to demonstrate the working of 
    # bisect(), bisect_left() and bisect_right() 
      
    # importing "bisect" for bisection operations 
    import bisect 
      
    # initializing list 
    li = [1, 3, 4, 4, 4, 6, 7] 
      
    # using bisect() to find index to insert new element 
    # returns 5 ( right most possible index ) 
    print ("The rightmost index to insert, so list remains sorted is  : ", end="") 
    print (bisect.bisect(li, 4)) 
      
    # using bisect_left() to find index to insert new element 
    # returns 2 ( left most possible index ) 
    print ("The leftmost index to insert, so list remains sorted is  : ", end="") 
    print (bisect.bisect_left(li, 4)) 
      
    # using bisect_right() to find index to insert new element 
    # returns 4 ( right most possible index ) 
    print ("The rightmost index to insert, so list remains sorted is  : ", end="") 
    print (bisect.bisect_right(li, 4, 0, 4)) 

    Output:

    The rightmost index to insert, so list remains sorted is  : 5
    The leftmost index to insert, so list remains sorted is  : 2
    The rightmost index to insert, so list remains sorted is  : 4
    

    Time Complexity:

    O(log(n)) -> Bisect method works on the concept of binary search


    # Python code to demonstrate the working of 
    # insort(), insort_left() and insort_right() 
      
    # importing "bisect" for bisection operations 
    import bisect 
      
    # initializing list 
    li1 = [1, 3, 4, 4, 4, 6, 7] 
      
    # initializing list 
    li2 = [1, 3, 4, 4, 4, 6, 7] 
      
    # initializing list 
    li3 = [1, 3, 4, 4, 4, 6, 7] 
      
    # using insort() to insert 5 at appropriate position 
    # inserts at 6th position 
    bisect.insort(li1, 5) 
      
    print ("The list after inserting new element using insort() is : ") 
    for i in range(0, 7): 
        print(li1[i], end=" ") 
      
    # using insort_left() to insert 5 at appropriate position 
    # inserts at 6th position 
    bisect.insort_left(li2, 5) 
      
    print("
    ") 
      
    print ("The list after inserting new element using insort_left() is : ") 
    for i in range(0, 7): 
        print(li2[i], end=" ") 
      
    print("
    ") 
      
    # using insort_right() to insert 5 at appropriate position 
    # inserts at 5th position 
    bisect.insort_right(li3, 5, 0, 4) 
      
    print ("The list after inserting new element using insort_right() is : ") 
    for i in range(0, 7): 
        print(li3[i], end=" ") 

    Output:

    The list after inserting new element using insort() is : 
    1 3 4 4 4 5 6 
    The list after inserting new element using insort_left() is : 
    1 3 4 4 4 5 6 
    The list after inserting new element using insort_right() is : 
    1 3 4 4 5 4 6 
    

    Time Complexity:

    O(n) -> Inserting an element in sorted array requires traversal
  • 相关阅读:
    利用print2flashsetup.exe文档转swf
    Linux 脚本内容指定用户执行
    第一讲:网络协议概述
    第三讲:ifconfig:最熟悉又陌生的命令行
    第2讲 | 网络分层的真实含义是什么?
    Fiddler -工具使用介绍(附:拦截请求并修改返回数据)(转)
    Fiddler 抓包工具总结(转)
    网络抓包wireshark(转)
    Axure RP 授权码
    第6堂视频课:看到词句就会读-下
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14366236.html
Copyright © 2011-2022 走看看