Python中bisect的使用方法

2021-10-12 04:19:03 字數 4079 閱讀 4023

python中列表(list)的實現其實是乙個陣列,當要查詢某乙個元素的時候時間複雜度是o(n),使用list.index()方法,但是隨著資料量的上公升,list.index()的效能也逐步下降,所以我們需要使用bisect模組來進行二分查詢,前提我們的列表是乙個有序的列表。

遞迴二分查詢和迴圈二分查詢

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 binary_search_recursion(lst, val, start, mid -1)

return mid

defbinary_search_loop

(lst, val)

: start, end =0,

len(lst)-1

while start <= end:

mid =

(start + end)//2

if lst[mid]

< val:

start = mid +

1elif lst[mid]

> val:

end = mid -

1else

:return mid

return

none

為了比對一下兩者的效能,我們使用timeit模組來測試兩個方法執行,timeit模組的timeit方法缺省會對需要測試的函式執行1000000,然後返回執行的時間。

'''

'''>>

>

import random

>>

>

from random import randint

>>

>

from random import choice

>>

> random.seed(5)

>>

> lst =

[randint(1,

100)

for _ in

range

(500000)]

>>

> lst.sort(

)>>

> val = choice(lst)

>>

> val

6>>

>

deftest_recursion()

:...

return binary_search_recursion(lst, val,0,

len(lst)-1

)...

>>

>

deftest_loop()

:...

return binary_search_loop(lst, val)..

.>>

>

import timeit

>>

> t1 = timeit.timeit(

"test_recursion()"

, setup=

"from __main__ import test_recursion"

)>>

> t1

3.9838006450511045

>>

> t2 = timeit.timeit(

"test_loop()"

, setup=

"from __main__ import test_loop"

)>>

> t2

可以看到,迴圈二分查詢比遞迴二分查詢效能要來的好些。現在,我們先用bisect的二分查詢測試一下效能

用bisect來搜尋

>>

>

import bisect

>>

>

defbinary_search_bisect

(lst, val):.

.. i = bisect.bisect(lst, val)..

.if i !=

len(lst)

and lst[i]

== val:..

.return i..

.return

none..

.>>

>

deftest_bisect()

:...

return binary_search_bisect(lst, val)..

.>>

> t3 = timeit.timeit(

"test_bisect()"

, setup=

"from __main__ import test_bisect"

)>>

> t3

1.3453236258177412

對比之前,我們可以看到用bisect模組的二分查詢的效能比迴圈二分查詢快一倍。再來對比一下,如果用python原生的list.index()的效能

>>

>

deftest_index()

:...

return lst.index(val)..

.>>

> t4 = timeit.timeit(

"test_index()"

, setup=

"from __main__ import test_index"

)>>

> t4

518.1656223725007

可以看到,如果用python原生的list.index()執行1000000,需要500秒,相比之前的二分查詢,效能簡直慢到恐怖

用bisect.insort插入新元素

排序很耗時,因此在得到乙個有序序列之後,我們最好能夠保持它的有序。bisect.insort就是為這個而存在的

insort(seq, item)把變數item插入到序列seq中,並能保持seq的公升序順序

'''

'''import random

from random import randint

import bisect

lst =

size =

10random.seed(5)

for _ in

range

(size)

: item = randint(

1, size)

bisect.insort(lst, item)

print

('%2d ->'

% item, lst)

輸出:

10

->[10

]5->[5

,10]6

->[5

,6,10

]9->[5

,6,9

,10]1

->[1

,5,6

,9,10

]8->[1

,5,6

,8,9

,10]4

->[1

,4,5

,6,8

,9,10

]1->[1

,1,4

,5,6

,8,9

,10]3

->[1

,1,3

,4,5

,6,8

,9,10

]2->[1

,1,2

,3,4

,5,6

,8,9

,10]

Python中bisect的使用

1 2 這裡,就我有疑問的地方做個記錄 第一,bisect模組中的函式都有哪些用途。根據python 的參考手冊,這個模組的主要用途是運用bisection algorithm 分半演算法 在已序的列表中進行查詢和插入操作。練習中使用了bisect left a,x 函式,這個函式給出了x元素在列表...

Python中bisect的用法

一般來說,python中的bisect用於操作排序的陣列,比如你可以在向乙個陣列插入資料的同時進行排序。下面的 演示了如何進行操作 import bisect import random random.seed 1 print new pos contents print l for i in ra...

Python中bisect的使用方法

python中列表 list 的實現其實是乙個陣列,當要查詢某乙個元素的時候時間複雜度是o n 使用list.index 方法,但是隨著資料量的上公升,list.index 的效能也逐步下降,所以我們需要使用bisect模組來進行二分查詢,前提我們的列表是乙個有序的列表。遞迴二分查詢和迴圈二分查詢 ...