在Python中使用范围作为字典索引

时间:2016-02-09 08:32:31

标签: python dictionary

是否可以执行以下操作:

r = {range(0, 100): 'foo', range(100, 200): 'bar'}

print r[42]

> 'foo'

所以我想使用数值范围作为字典索引的一部分。为了使事情变得更复杂,我还想使用像('a', range(0,100))这样的多索引。所以这个概念应该理想地扩展到那个。有什么建议吗?

类似的问题被问为here,但我对全面实施感兴趣,而不是该问题的不同方法。

7 个答案:

答案 0 :(得分:4)

如果您使用的是Python 3.x,则可以使用range对象作为键,但要检索值,您将执行以下操作:

In [33]: r = {range(0, 100): 'foo', range(100, 200): 'bar'}

In [34]: { r[key] for key in r if 42 in key}
Out[34]: {'foo'}

你不能在Python2.x中执行此操作的原因是因为版本2.7之后的range函数返回一个列表而列表不能用作字典键,因为它们不提供有效的{{3}方法。

答案 1 :(得分:3)

作为替代方法,如果您尝试查找与某些范围相关联的值,则可以使用内置的Python bisect库,如下所示:

import bisect

def boundaries(num, breakpoints=[100, 200], result=['foo', 'bar']):
    i = bisect.bisect(breakpoints, num-1)
    return result[i]

print boundaries(42)

这会显示:

foo

答案 2 :(得分:2)

您只能使用不可变数据类型作为键。所以没有名单。

但你可以使用一个tupel来定义上限和下限。

man git-clone

我会以这种方式得到42的值:

r = {(0,100): 'foo', (100,200): 'bar'}

但我承认你不需要字典。

答案 3 :(得分:2)

如果您有一种简单的方法来计算某个点的范围,例如,如果所有范围都是固定大小,您可以使用:

def getIndex(p):
   start = floor(p/100)*100
   return (start, start+100)

然后定义dict:

r = {(0, 100): 'foo', (100, 200): 'bar'}

并访问:

r[getIndex(42)]

这种方法效率很高:

  1. 你没有在dict中为该范围内的每个数字持有一个项目(这也允许你有真正的价值“键”)
  2. 你不是要通过整个字典找到一个值,得到一个值是O(1)
  3. 此外,您的getIndex函数可能更复杂,例如,如果您的范围在长度上不规则,则getIndex函数可以二进制搜索范围边界的排序列表并返回范围元组,不再O(1)O(log(n))也不错......

答案 4 :(得分:0)

你可以用这个:

r=dict(zip(range(100),["foo"]*100))
r2=dict(zip(range(100,200),["bar"]*100))
r.update(r2)

答案 5 :(得分:0)

你可以在一行中完成

r = dict(zip(range(200),["foo"]*100+["bar"]*100))

答案 6 :(得分:0)

您可以使用list comprehension获取所需的词典:

d = dict([(i,'foo') for i in range(0, 100)] + [(i,'bar') for i in range(100, 200)])
print d
相关问题