选择多个执行路径之一或依赖于变量的数据位的Pythonic方法是使用哈希表,如下所示:
mapping = {'bar':"xyzzy", 'foo':"plugh", 'baz':"frobnitz"}
magic = mapping[command]
如果我想根据值是否在多个值范围之一中选择执行路径,我该怎么办?
或者,更简洁地说,我如何对此进行pythonicize:
#A value from one to four indicates an O-type star. 4/58 chance.
if typeselec <= 4:
self.specttype="O"
#A value from 5-20 indicates a B-type star. 15/58 chance.
elif typeselec <= 20:
self.specttype="B"
#A value from 20-30 indicates an A-type star. 10/58 chance.
elif typeselec <= 30:
self.specttype="A"
#A value from 31-36 indicates an F-type star. 6/58 chance.
elif typeselec <= 36:
self.specttype="F"
#A value from 37-40 indicates a G-type star. 4/58 chance.
elif typeselec <= 40:
self.specttype="G"
#A value from 41-50 indicates a K-type star. 10/58 chance.
elif typeselec <= 22:
self.specttype="K"
#A value from 50-58 indicates an M-type star. 8/58 chance.
else:
self.specttype="M"
一个明显的方法是{1:'O', 2:'O',3:'O',4:'O',5:'B',6:'B'...}
,但这看起来非常不优雅和效率低下。还有其他办法吗?
答案 0 :(得分:3)
正是这种类型或问题被用作bisect模块的示例。
适应您的问题,它看起来像这样:
from bisect import bisect_left
def select_type(typeselec,
breakpoints=[4, 20, 30, 36, 40, 50],
types='0BAFGKM'):
return types[bisect_left(breakpoints, typeselec)]
for i in range(59):
print(i, select_type(i))
与doc的示例的不同之处在于,断点是下界(<=
)的一部分,其中在示例中它是上部的一部分(>=
),因此需要使用bisect_left
代替bisect
(bisect_right
的别名)。
Altough bisect
的时间复杂度不是O(1)
,它使用二进制搜索,因此它的时间复杂度为O(log(n))
,对于较大的n
} O(n)
级联的if
将是一个很好的改进。
答案 1 :(得分:2)
将您的specttype
存储在加权列表中,并以typeselec
作为索引进行查找。生成列表后,查找为O(1)。
letters = 'OBAFGKM'
frequencies = (4, 15, 10, 6, 4, 10, 8)
specttypes = []
for i in range(len(letters)):
l = letters[i]
f = frequencies[i]
specttypes = specttypes + [l] * f
self.specttype = specttypes[typeselec-1] # Subtract 1 because of zero indexing.
您可以使用字典而不是单独的可迭代letters
和frequencies
,但结果specttypes
将按字母顺序排序,除非您使用ordered dictionary。
请注意specttypes
有57个元素,如上所定义,而不是你提到的58个元素。那是因为你的上一个代码评论自相矛盾;我指定了&#39; M&#39;频率为8而不是9(即,指数50-57而不是50-58)。
答案 2 :(得分:0)
如果我们有一大组范围,我会将数字存储在排序的序列中,并使用bisect进行二分搜索;它的O(log(n))用于查找而不是O(n)。仍然不是完美哈希的O(1)。当然,在您展示的非常有限的集合中,您可以将值存储在单个字符串中并将其用作普通查找表。 chikinn的例子是这样做的,但有一个列表(考虑到它,会更高效 - 不需要查找字符串的字符串版本)。