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
  • 相关阅读:
    数学符号表
    对比深度学习十大框架:TensorFlow最流行但并不是最好
    支持向量机通俗导论(理解SVM的三层境界)
    Annotation
    Struts2的拦截器
    DLL文件的引用
    JS引擎
    Windows窗口的创建
    解决构造器多参数的设计问题
    静态工厂对比构造器之优缺点
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14366236.html
Copyright © 2011-2022 走看看