如果这很明显,请原谅我,但我对Python非常非常新。我已经找到了从字典中获取多个键的方法,但这不是我想要做的。
基本上我正在寻找这样的东西:
my_dict = { "1-10" : "foo",
"11-20" : "bar",
# ...
"91-100" : "baz" }
...但是其中键实际上不是字符串,并且该给定范围中的任何数字都映射到该值。例如,my_dict[9]
应该返回foo
,就像my_dict[3]
一样。我想过使用一个显式数组,如下所示,但它不起作用:
my_dict = { [1, 2, 3, ..., 10] : "foo",
我不确定这是否是字典的有效用例,或者我是否应该使用其他数据结构。但Python有一种令我惊讶的方式。那么有谁知道Python魔术才能使它发挥作用?
答案 0 :(得分:3)
我必须说我从来没有必要做这样的事情,而且肯定没有内置的数据结构。 (如果你对哈希有所了解,你就会理解为什么dict不能那样工作。)
一种可能性是根本不使用dict,而是使用单独的键和值列表,键列表是每个“范围”的开头。所以:
keys = [0, 10, 20, 30]
values = ['foo', 'bar', 'baz', 'quux']
现在您可以使用bisect
查找相关密钥:
import bisect
pos = bisect.bisect_left(keys, 12)
value = values[pos-1]
答案 1 :(得分:2)
这当然不是常见的情况,我建议使用明显的解决方案:
my_dict = dict((i, "foo") for i in range(1,10))
print my_dict
{1: 'foo', 2: 'foo', 3: 'foo', 4: 'foo', 5: 'foo', 6: 'foo', 7: 'foo', 8: 'foo', 9: 'foo'}
为了添加新元素,您可以使用以下命令更新字典:
my_dict.update(new_elements)
答案 2 :(得分:1)
如果你的“范围键”是简单的数学变换,每个潜在的有效键都有唯一的映射,你可以只是list
的子类并覆盖__getitem__
和__setitem__
,尽管有充分的理由只需在调用代码中使用辅助方法或直接计算(例如让index()
返回特别有意义的内容)。
class RangeList(list):
def __getitem__(self, index):
return super(RangeList, self).__getitem__(index / 10 if index else 0)
def __setitem__(self, index, value):
super(RangeList, self).__setitem__(index / 10 if index else 0, value)
答案 3 :(得分:1)
这个怎么样:
def fancy_dict(*args):
'Pass in a list of tuples, which will be key/value pairs'
ret = {}
for k,v in args:
for i in k:
ret[i] = v
return ret
然后,你可以:
>>> dic = fancy_dict((range(10), 'hello'), (range(100,125), 'bye'))
>>> dic[1]
'hello'
>>> dic[9]
'hello'
>>> dic[100]
'bye'
>>>
您还可以在fancy_dict
内添加逻辑来说明,检查项目是否为字符串,或者是否可迭代,并相应地创建字典。
答案 4 :(得分:0)
我保留此记录,也可能有其他人感兴趣:
如果你制作键元组它是有效的: my_dict = {(1,2,3,10):“foo”}
修改:我认为你想要一个列表作为关键。 否则,你需要做到:
>>> import numpy as np
>>> keys = np.arange(10,dtype=int)
>>> values = np.arange(3,13)
>>> d = dict(numpy.array([keys,values]).T)
>>> d
{0: 3, 1: 4, 2: 5, 3: 6, 4: 7, 5: 8, 6: 9, 7: 10, 8: 11, 9: 12}
答案 5 :(得分:0)
mabey你可以沿着这条线做点什么:
class my_dict(dict):
def __getitem__(self, a):
return dict.__getitem__(self, (a-1) / 10)
def __setitem__(self, a, b):
dict.__setitem__(self, (a-1) / 10, b)
dict_instance = my_dict()
dict_instance[1] = 'foo'
print dict_instance[9] # prints foo
dict_instance[17] = 'bar'
print dict_instance[12] # prints bar
这有点像正常字典(O(1))一样快但是小10倍
如果你想要打印范围,还需要ovewrite __ str__,你也可以使用这种数据类型非常容易地遍历唯一键:)