[Python]bisect模块介绍

本文详细介绍了如何使用Python的bisect模块在有序列表中插入数据并保持列表的有序性,同时讲解了如何查找数据在有序列表中的正确位置。通过具体示例解释了bisect_left、bisect_right、insort_left和insort_right函数的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

希望将一个数据插入到一个有序列表中,插入后不改变整个序列的顺序。

从下面的例子可以看出,插入新数据的列表仍保持升序。

a=[0,4,7,10,15]
b=14
# 最终得到[0,4,7,14,15]

上面表红的是需要注意的两点:

  1. 待插入的数据必须是int类型
  2. 列表中保存的是int类型数据,并且按照升序排列

解决方法

使用python内置模块bisect。

import bisect

将数据插入到列表的时候,最常见的是两个需求:

  1. 不要将数据插入列表,只需要返回数据在有序列表中的位置
  2. 需要将数据插入列表中,并且保持列表的有序性

需求1:返回位置索引

bisect.bisect_left(a, x, lo=0, hi=len(a)) 

其中,a是有序列表,x是目标数据,返回值是x在a中的位置索引。如果x与a中的数据相等,则返回相等数据左侧的位置索引。

举例说明,可以将a中的元素看做分割点,将整个有理数空间分成len(a)+1份,假设a=[a1,a2,a3,a4],则划分后的空间范围为:

  [sub_space]    (negtive_inf,a1]  (a1,a2]  (a2,a3]  (a3,a4]  (a4,postive_inf)

            |                     |                     |             |             |                |

       [index]                0                    1            2            3               4

如果目标数据在子空间范围内,就会返回相应的位置索引;如果恰好等于边界值,则返回左侧的位置索引,即子空间的左边界是不包含关系,右边界是包含关系,这正是“left”的含义。比如x=a2,返回a2左侧的索引,即(a1,a2],索引值为1.

bisect.bisect_right(a, x, lo=0, hi=len(a)) 
bisect.bisect(a, x, lo=0, hi=len(a))        # bisect是bisect_right的别名

bisect_right和bisect_left的区别可以使用上面的例子来说明,唯一的区别在于如果目标数据与边界值相同,返回的是边界值右侧的索引,即子空间左边界是包含关系,右边界是不包含关系,这正是“right”的含义

  [sub_space]    (negtive_inf,a1)  [a1,a2)  [a2,a3)  [a3,a4)  [a4,postive_inf)

            |                     |                     |             |             |                |

       [index]                0                    1            2            3               4

需求2:将数据插入有序列表并保持列表有序性

bisect.insort_left(a, x, lo=0, hi=len(a)) 

将x插入到a中,并保持a的有序性。如果遇到x与a中元素相等的情况,将x插入到相等元素的左侧。

bisect.insort_right(a, x, lo=0, hi=len(a)) 
bisect.insort(a, x, lo=0, hi=len(a)) 

唯一的区别在于如果遇到x与a中元素相等的情况,将x插入到相等元素的右侧。

bisect的局限性

bisect只能处理int类型的数据,对于复杂的数据类型就无能为力了。

data = [('black', 0), ('blue', 1), ('red', 5), ('yellow', 8)]
x = ('grey', 3)

希望将x插入按照第二项的大小插入到data中,使用bisect.insort()将无法实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值