3.6. bisect — 维护有序列表

未匹配的标注

本节目标: 每次有数据添加到列表时维护列表的有序性但无需调用排序功能。

bisect 模块里实现了一个向列表插入元素时也会顺便排序的算法。

以排序方式插入

下面是一个使用 insort() 方法将数据以排序后的顺序插入到列表的例子。

bisect_example.py

import bisect

# 一些随机数
values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1]

print('New  Pos  Contents')
print('---  ---  --------')

l = []
for i in values:
    position = bisect.bisect(l, i)
    bisect.insort(l, i)
    print('{:3}  {:3}'.format(i, position), l)

第一列输出表示插入的随机数是多少。第二列表示这个随机数应该在列表中插入的位置。其余的部分则是插入数据后得到的列表。

$ python3 bisect_example.py

New  Pos  Contents
---  ---  --------
 14    0 [14]
 85    1 [14, 85]
 77    1 [14, 77, 85]
 26    1 [14, 26, 77, 85]
 50    2 [14, 26, 50, 77, 85]
 45    2 [14, 26, 45, 50, 77, 85]
 66    4 [14, 26, 45, 50, 66, 77, 85]
 79    6 [14, 26, 45, 50, 66, 77, 79, 85]
 10    0 [10, 14, 26, 45, 50, 66, 77, 79, 85]
  3    0 [3, 10, 14, 26, 45, 50, 66, 77, 79, 85]
 84    9 [3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85]
 77    8 [3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
  1    0 [1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]

这个例子比较简单,实际上,考虑到要排序的数据量,简单的创建一个列表然后进行一次排序可能要快很多。相比之下,对于长列表来说,使用这种算法能很好得节约时间和节省内存,尤其是在对比两个元素需要花费大量计算的时候。

对重复的数据的处理

从之前的结果集合中我们可以看到有一个重复的数字 77,对于重复的值, bisect 模块提供了两种方法来进行处理:你可以选择将新值插到旧值的左边,也可以插到右边。 insort() 函数实际上是 insort_right() 函数,这个函数会将新值插到旧值的右边。与它相当的函数 insort_left() 则是将值插到旧值的左边。

bisect_example2.py

import bisect

# 一些随机数
values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1]

print('New  Pos  Contents')
print('---  ---  --------')

# 使用 bisect_left 和 insort_left 来进行后续操作。
l = []
for i in values:
    position = bisect.bisect_left(l, i)
    bisect.insort_left(l, i)
    print('{:3}  {:3}'.format(i, position), l)

同样的数据使用 bisect_left()insort_left() 操作后结果并不会有什么不同,只是遇到相同的值时,插入的位置不一样。

$ python3 bisect_example2.py

New  Pos  Contents
---  ---  --------
 14    0 [14]
 85    1 [14, 85]
 77    1 [14, 77, 85]
 26    1 [14, 26, 77, 85]
 50    2 [14, 26, 50, 77, 85]
 45    2 [14, 26, 45, 50, 77, 85]
 66    4 [14, 26, 45, 50, 66, 77, 85]
 79    6 [14, 26, 45, 50, 66, 77, 79, 85]
 10    0 [10, 14, 26, 45, 50, 66, 77, 79, 85]
  3    0 [3, 10, 14, 26, 45, 50, 66, 77, 79, 85]
 84    9 [3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85]
 77    7 [3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]
  1    0 [1, 3, 10, 14, 26, 45, 50, 66, 77, 77, 79, 84, 85]

参考

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/pymotw/bisect-m...

译文地址:https://learnku.com/docs/pymotw/bisect-m...

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~