Python:Range()作为字典值

时间:2012-10-08 00:03:05

标签: python dictionary range

假设我有一个类似下面的词典,其中值是每个键在文本中显示的概率。

   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

有人可以帮帮我吗?我很难搞清楚要做什么!

2 个答案:

答案 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