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

本问题已经有最佳答案,请猛点这里访问。

是否可以做如下的事情:

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

print r[42]

> 'foo'

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

这里也提出了类似的问题,但我对全面的实施感兴趣,而不是对该问题的不同方法感兴趣。

范围是固定的吗?比如说,对于某个整数x,都是range(x*100, (x+1)*100)?

@假尘埃:是的,固定范围

考虑到问题的放松,我会给出一个更简单、更有效的答案。

看看这个质量保证。它与:class RangeDictionary(TransformedDict): def __keytransform__(self, key): dk = sorted(self.keys()) return dk[bisect.bisect(dk, key)],然后r = RangeDictionary({100: 'foo', 200: 'bar', 250: 'xyz'}); print(r[42]); print(r[142]); print(r[242])生产foo bar xyz。仅覆盖def __getitem__(self, key): return self.store[self.__keytransform__(key)]。

如果您在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函数返回一个列表,并且列表不能用作字典键,因为它们不提供有效的__hash__方法。

很好,谢谢。现在真的是时候转向Python3了。不幸的是,这个项目是在2.7。

作为一种替代方法,如果您试图查找与特定范围相关的值,可以使用内置的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

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

def getIndex(p):

start = floor(p/100)*100

return (start, start+100)

然后定义听写:

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

和访问:10

该方法的有效性如下:

您没有为范围内的每个数字保留dict中的项目(这也允许您拥有真正的值"keys")。

您不需要通过整个dict来查找值,得到的值是o(1)

另外,您的getIndex函数可能更复杂,例如,如果您的范围在长度上不规则,您的getIndex函数可以二进制搜索范围边界的排序列表并返回范围元组,不再是O(1),但O(log(n))也不错……

只能将不可变的数据类型用作键。所以没有列表。

但可以使用元组定义上界和下界。

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

我可以这样得到42的值:

res =""

for (k1,k2) in r:

if (k1 < 42 and k2 > 42):

res = r[(k1,k2)]

print(res)

但我承认你不需要字典。

编辑了我的答案

谢谢-我现在该怎么办?:)

添加到我的答案中

您可以使用列表理解获得所需的字典:

d = dict([(i,'foo') for i in range(0, 100)] + [(i,'bar') for i in range(100, 200)])

print d

你可以排成一行

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

你可以用这个:

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

r2=dict(zip(range(100,200),["bar"]*100))

r.update(r2)

现在这是正确的方法!我很高兴有人强调。

这是低效的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值