存储映射到字符串的整数的最佳方法是什么,以便键可以是python中的范围?

时间:2009-10-22 09:50:16

标签: python types

存储(非可变)格式数据的最佳方法是什么:

doodahs = {
0-256: "FOO",
257: "BAR",
258: "FISH",
279: "MOOSE",
280-65534: "Darth Vader",
65535: "Death to all newbies" }

我有相对大量的这类数据集,所以我可以定义字典的方式(或接近它)并通过索引访问。

哦,这是在Python 2.4上,所以如果你想让我使用更新的版本,那么请给出非常好的升级理由(我会选择3:)

4 个答案:

答案 0 :(得分:5)

我将范围拆分为元组,然后在课堂内,将项目保存在有序列表中。您可以使用bisect模块进行插入O(n)和查找O(logn)。

如果要将字典转换为新类,则可以构建无序列表并在最后对其进行排序

doodahs = [
    (0, 256, "FOO"),
    (257, 257, "BAR"),
    (258, 258, "FISH"),
    (279, 279, "MOOSE"),
    (280, 65534, "Darth Vader"),
    (65535, 65535, "Death to all newbies")]

您的__getitem__可能会起到以下作用:

def __getitem__(self, key):
    return self.doodahs[bisect.bisect(self.doodahs, (key,))]

__setitem__可能是这样的:

def __setitem__(self,range,value):
    bisect.insort(self.doodahs, range+(value,))

答案 1 :(得分:2)

如果你的整数的上限小于几百万,那么你只需将范围扩展为单个值。

class RangedDict( dict ):
    def addRange( self, iterator, value ):
        for k in iterator:
            self[k]= value

d= RangedDict()
d.addRange( xrange(0,257), "FOO" )
d[257]= "BAR"
d[258]= "FISH"
d[279]= "MOOSE"
d.addRange( xrange(280,65535), "Darth Vader" )
d[65535]= "Death to all newbies"

您的所有查找都有效,并且是即时的。

答案 2 :(得分:1)

鉴于您的密钥中没有任何“缺口”,为什么您只是不存储每个分段的开头,然后像建议的那样使用bisect查找?

doodahs = (
    (0, "FOO"),
    (257, "BAR"),
    (258, "FISH"),
    (279, "MOOSE"),
    (280, "Darth Vader"),
    (65535, "Death to all newbies")
)

答案 3 :(得分:0)

class dict2(dict):
    def __init__(self,obj):
            dict.__init__(self,obj)
    def __getitem__(self,key):
            if self.has_key(key):
                    return super(dict2,self).__getitem__(key)
            else:
                    for k in self:
                            if '-' in k:
                                    [x,y] = str(k).split('-')
                                    if key in range(int(x),int(y)+1):
                                            return super(dict2,self).__getitem__(k)
                    return None


d = {"0-10":"HELLO"}
d2 = dict2(d)
print d,d2,d2["0-10"], d2[1]