假设我有一个类似下面的词典,其中值是每个键在文本中显示的概率。
dict = {'a':0.66,'b':0.07,'c':0.04 and so on so the values of the dict sum up to one}
说我想要构建另一个字典,其中包含这些值的范围。 由于我们不能将range()与浮点数一起使用,我试图先将所有值乘以100,因此它们变为int。 假设我们想用它们的范围替换这些值。所以例如'a'将获得范围(0,66),'b'范围(66,73),'c'(73,77)等。 我试图通过以下循环来做到这一点,但它不起作用:
start = 0
end = 0
for k,v in dict.items():
end+=int(v*100)
range_dict[k]=range(start,end)
start+=end
有人可以帮帮我吗?我很难搞清楚要做什么!
答案 0 :(得分:3)
如果你改变了
start += end
到
start = end
它应该有用(在这里使用xrange
使其更加明显):
>>> d = {'a':0.66,'b':0.07,'c':0.04}
>>> start = 0
>>> end = 0
>>> range_dict = {}
>>> for k,v in d.items():
... end+=int(v*100)
... range_dict[k]=xrange(start,end)
... start=end
...
>>> range_dict
{'a': xrange(66), 'c': xrange(66, 70), 'b': xrange(70, 77)}
但如果@ Satoru.Logic猜测你想要一个加权随机数,那么有更好的方法。 Eli Bendersky对Python here中的方法有很好的概述。
答案 1 :(得分:0)
在Python 3.3.0文档中自豪地被盗:
random - 9.6.2. Examples and Recipes - 包含加权分配算法 itertools.accumulate - 包含累积算法。
以下代码是为2.X编写的:
import random
import bisect
D = {'a':0.66,'b':0.07,'c':0.04,'d':0.20,'e':0.03}
# This function is in Python 3.2+ itertools module.
def accumulate(iterable):
'Return running totals'
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
it = iter(iterable)
total = next(it)
yield total
for element in it:
total = total + element
yield total
# Extract the weights and build a cumulative distribution.
choices, weights = zip(*D.items())
cumdist = list(accumulate(weights))
# Make 1000 random selections
L = [choices[bisect.bisect(cumdist, random.random() * cumdist[-1])]
for _ in xrange(1000)]
# Display the results
for c in sorted(D.keys()):
print '{} {:3d}'.format(c,L.count(c))
输出:
a 652
b 72
c 43
d 200
e 33