是否可以执行以下操作:
r = {range(0, 100): 'foo', range(100, 200): 'bar'}
print r[42]
> 'foo'
所以我想使用数值范围作为字典索引的一部分。为了使事情变得更复杂,我还想使用像('a', range(0,100))
这样的多索引。所以这个概念应该理想地扩展到那个。有什么建议吗?
类似的问题被问为here,但我对全面实施感兴趣,而不是该问题的不同方法。
答案 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)]
这种方法效率很高:
此外,您的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