The implementation of the list in Python is actually an array, when the time complexity is O (n) to find an element, and the List.index () method is used, but as the amount of data increases, the performance of List.index () is gradually declining, So we need to use the Bisect module for binary lookups, provided our list is an ordered list.
Recursive binary lookup and cyclic binary lookup
def binary_search_recursion (LST, Val, start, end): If Start > End: return None mid = (start + end)//2
if Lst[mid] < val: return Binary_search_recursion (LST, Val, mid + 1, end) if Lst[mid] > val: return bin Ary_search_recursion (LST, Val, start, mid-1) return middef Binary_search_loop (LST, Val): start, end = 0, Len (LST )-1 while start <= end: mid = (start + end)//2 if Lst[mid] < val: start = mid + 1 elif l St[mid] > val: end = mid-1 else: return mid return None
In order to compare the performance of the two, we use the Timeit module to test two method execution, the Timeit module's Timeit method defaults to the function that needs to be tested 1000000, and then returns the time of execution.
>>> import random>>> from the random import randint>>> from random import choice>>> Rando M.seed (5) >>> lst = [Randint (1, +) for _ in range (500000)]>>> Lst.sort () >>> val = choice (LST) & Gt;>> val6>>> def test_recursion (): ... Return Binary_search_recursion (LST, Val, 0, Len (LST)-1) ...>>> def test_loop (): ... Return Binary_search_loop (LST, Val) ...>>> import timeit>>> t1 = Timeit.timeit ("Test_recursion ()", setup= "from __main__ import test_recursion") >>> t13.9838006450511045>>> t2 = Timeit.timeit ("Test_ Loop () ", setup=" from __main__ import Test_loop ") >>> t22.749765167240339
As you can see, cyclic binary lookups are better than recursive binary lookup performance. Now, let's test the performance with Bisect's binary search.
Use Bisect to search
>>> Import bisect>>> def binary_search_bisect (LST, val): ... i = Bisect.bisect (LST, val) ... If I! = Len (LST) and lst[i] = = Val: ... return I ... Return none...>>> def test_bisect (): ... Return Binary_search_bisect (LST, val) ...>>> t3 = Timeit.timeit ("Test_bisect ()", setup= "from __main__ Import Test_bisect ") >>> t31.3453236258177412
Before we compare, we can see that the performance of binary lookup with the Bisect module is one-fold faster than the cyclic two-part lookup. In contrast, if the performance of native List.index () with Python
>>> def test_index (): ... Return Lst.index (val) ...>>> t4 = Timeit.timeit ("Test_index ()", setup= "from __main__ import Test_index") > >> t4518.1656223725007
As you can see, if you execute 1000000 with Python native List.index (), it takes 500 seconds, and the performance is really slow to the horror compared to the previous binary search.
Inserting new elements with Bisect.insort
Sorting is time-consuming, so we'd better be able to keep it in order after we get an ordered sequence. Bisect.insort is the one who exists for this.
Insort (SEQ, item) Inserts the variable item into the sequence SEQ and keeps the SEQ ascending order
Import randomfrom Random import randintimport bisectlst = []size = 10random.seed (5) for _ in range (SIZE): item = Randin T (1, SIZE) bisect.insort (LST, item) print ('%2d, '% item, LST)
Output:
[5]---[5, 6]-------6, 9, 5, ten] 6---[9, 1, 1, 5, ten] 6, [9, 8, 1, 5, 6, 8 ] 4, [1, 4, 5, 6, 8, 9, ten] 1----[1, 1, 4, 5, 6, 8, 9, ten] 3, [1, 1, 3, 4, 5, 6, 8, 9,] 2, [1, 1, 2, 3, 4, 5, 6, 8, 9, 10]
How to use bisect in Python