如何更好地实施这样的事情:
循环数字。 diapason中的每个数字都属于关联数组的一部分。
E.g。
di = {}
di[ xrange(0,10) ] = "A"
di[ xrange(11,20) ] = "B"
di[ xrange(21,30) ] = "C"
direction = di[ 24 ]
# direction should be "C"
direction = di[ 6 ]
# direction should be "A"
编辑使用谨慎的数字填充整个di
不是我的方式,因为我说的是IP地址,真正的大数据,例如netmasks 255.255.255.255。这样的di
会溢出我的RAM。
答案 0 :(得分:1)
我会创建一个以xrange为键的自定义词典:
class DictRange(dict):
def __getitem__(self, val):
for key in self.keys():
if val in key:
return super(DictRange,self).__getitem__(key)
缺点是您必须通过所有键才能找到您的元素。使用那样:
di = DictRange()
di[ xrange(0,10) ] = "A"
di[ xrange(11,20) ] = "B"
di[ xrange(21,30) ] = "C"
print di[24]
# C
print di[6]
# A
使用bisect并假设您可以在初始化期间节省一些时间以加快访问速度,您可以执行以下操作:
import bisect
class DictRange(dict):
def __setitem__(self, key, val):
super(DictRange,self).__setitem__(key, val)
self.ks = [key[0] for key in self.keys()]
def __getitem__(self, val):
return super(DictRange,self).__getitem__(self.keys()[bisect.bisect(self.ks, val) - 1])
获取将为O(logn)
,其中n是键的数量,但该组将变为O(n)
。至于下一个解决方案,它依赖于连续的范围。
另一种解决方案可能会更快,具体取决于您的范围大小,将用作关键字范围的第一项,以及一个二等分来找到正确的关键字:
import bisect
ranges = [0, 11, 21, 31]
di = {}
di[0] = 'A'
di[11] = 'B'
di[21] = 'C'
di[31] = 'unknown' # special value to indicate the end of the range
print di[ranges[bisect.bisect(ranges, 24) - 1]]
# C
print di[ranges[bisect.bisect(ranges, 6) - 1]]
# A
print di[ranges[bisect.bisect(ranges, 31) - 1]]
# Unknown
这会快得多。 bisect
为O(logn)
,其中n
是范围数,其余为O(1)
答案 1 :(得分:0)
如果您不想填写字典,只需使用一个函数
from __future__ import division
import string
def return_ltr(i):
n = i//10
return string.ascii_uppercase[n]
否则,如果要填充字典,请执行以下操作。您当前的代码正在生成xrange objects
并将其用作键。但是,这与使用键的数字不同。请尝试以下方法,
import string
d = {}
i = 0
for ltr in string.ascii_uppercase:
for j in xrange(10):
d[i] = ltr
i += 1
如果您只想要字母的子集,则可以切片string.ascii_uppercase
。例如,使用string.ascii_uppercase[0:3]
只会为您提供A
,B
和C
。
答案 2 :(得分:0)
di = dict.fromkeys(xrange(0, 10), 'A')
di.update(dict.fromkeys(xrange(10, 20), 'B'))
di.update(dict.fromkeys(xrange(20, 30), 'C'))
print(di)
产量
{0: 'A', 1: 'A', 2: 'A', 3: 'A', 4: 'A', 5: 'A', 6: 'A', 7: 'A', 8: 'A', 9: 'A', 10: 'B', 11: 'B', 12: 'B', 13: 'B', 14: 'B', 15: 'B', 16: 'B', 17: 'B', 18: 'B', 19: 'B', 20: 'C', 21: 'C', 22: 'C', 23: 'C', 24: 'C', 25: 'C', 26: 'C', 27: 'C', 28: 'C', 29: 'C'}
请注意xrange(N, M)
生成从N
开始到M-1
(包括)结尾的整数。因此,如果您想在密钥中包含10,20,则xrange应为xrange(10, 20)
和xrange(20, 30)
。
答案 3 :(得分:0)
您可以使用元组而不是列表来解决TypeError
(您的代码不会引发FWIW),但查找仍然不起作用。可能最有效的方法是用给定值的每个离散键填充dict,即:
map = (
(0, 10, "A"),
(11, 20, "B"),
# etc
)
d = {}
for start, stop, val in map:
for k in xrange(start, stop):
d[k] = val