Python用两个list模拟有序字典

来源:互联网 发布:美图秀秀软件安装包 编辑:程序博客网 时间:2024/05/22 12:28

python语言中的dict(字典)类型是无序的。但是,实际中,我们有时会用到有序字典这种结构,也就是在一个有序的结构中存储一系列键值对。这里介绍的是,如何用两个list来实现这个结构。

1、bisect模块

1.1 介绍

python中的bisect模块可以实现向有序列表中插入元素,同时维护列表的顺序。bisect的实现也比较简单,大致的原理是首先使用二分查找,查找应该插入的位置,然后用list的insert方法将元素插入到指定的位置。bisect模块的代码不多,总共不到100行,而且非常简单易读。

从代码可以看出,bisect模块中,主要实现了四个函数,功能如下:

  • bisect.bisect_left(a,x, lo=0, hi=len(a)):查找在有序列表a中插入x的index。lo和hi用于指定列表的区间,默认是使用整个列表。如果x已经存在,在其左边插入。返回值为index。
  • bisect.bisect_right(a,x, lo=0, hi=len(a))与bisect.bisect(a, x,lo=0, hi=len(a))和bisect_left类似,但如果x已经存在,在其右边插入。返回值同样为index
  • bisect.insort_left(a,x, lo=0, hi=len(a)):在有序列表a中插入x,相当于a.insert(bisect.bisect_left(a,x, lo, hi), x)。该函数默认没有返回值。
  • bisect.insort_right(a,x, lo=0, hi=len(a))与bisect.insort(a, x,lo=0, hi=len(a))和insort_left类似,但如果x已经存在,在其右边插入。同样,这两个函数也没有返回值。
其实,由于简单bisect里面的这四个函数,既容易理解,也容易记忆。bisect_*的函数主要是用来查找插入的位置,insort_*函数是直接将元素放入相应的位置,完成插入。从bisect模块的实现可以看出,bisect模块中insort函数的插入实现实际上用的就是bisect函数返回的index。所以,在实际中,bisect函数返回的index,也可以直接用在list的insert函数中作为插入位置参数。

1.2 例子

下面是在python交互模式下使用bisect模块的几个例子:

>>> import bisect>>> a = []>>> bisect.bisect(a, 3)0>>> bisect.insort(a,3)>>> print a[3]>>> bisect.insort(a,5)>>> bisect.insort(a,1)>>> print a           [1, 3, 5]>>> bisect.bisect(a, 4)2>>> bisect.insort(a, 4)      >>> print a[1, 3, 4, 5]>>> 
2、用两个数组来模拟有序字典

这里采用的是最简单的方式,就是用两个数组一个存key、另一个寸value。下面的代码中,还实现了size的设定,维护结构中的总的元素个数,不能超过5,也就是说最多存5个元素(当然,如果你的代码中不需要,可以将size限定的代码去掉)。代码如下:

import bisectdef add_to_list(key_list, value_list, k, v):     '''     The parameter key_list and value_list should be [] or [some elements that positioned in an ascending order].    This function add k,v pair to the key_list and value_list respectively, keeping the orginal order.    Return value: the position that the k,v pair is inserted. The position is where the new-inserted element located after insertion.    '''    if len(value_list) < 5:        #find the insertion postion        position = bisect.bisect(value_list,v)        key_list.insert(position,k)        value_list.insert(position, v)    else:        if v > value_list[0]:            #find the insertion postion            position = bisect.bisect(value_list,v)            key_list.insert(position,k)            value_list.insert(position, v)            del(value_list[0])            del(key_list[0])    return positionif __name__ == "__main__":    lk1 = ["zz"]    lv1 = [2626]    lk = ["bb","ee","cc","aa","dd"]    lv = [22,55,33,11,44]    for i in range(0,5):        position = add_to_list(lk1,lv1,lk[i],lv[i])        print '%3d  %3d' % (lv[i],position),lv1, lk1     print "Over!"
这段代码的运行结果如下:

$ python test.py 22    0 [22, 2626] ['bb', 'zz'] 55    1 [22, 55, 2626] ['bb', 'ee', 'zz'] 33    1 [22, 33, 55, 2626] ['bb', 'cc', 'ee', 'zz'] 11    0 [11, 22, 33, 55, 2626] ['aa', 'bb', 'cc', 'ee', 'zz'] 44    3 [22, 33, 44, 55, 2626] ['bb', 'cc', 'dd', 'ee', 'zz']Over!
好了,就到这里了。可以看出,python的好处就是不用费尽心思去写二分查找这类的代码,减少重复工作。程序员只需要focus在自己要解决的问题上,这样工作量就小了。^_^

0 0
原创粉丝点击