Python Dictionary,使范围与其值相关联并返回它们

时间:2016-02-12 16:18:05

标签: python-3.x

说,我有一本字典

 D = {'A':0.25,'C':0.25,'G':0.25,'T':0.25}

字典值的总和将始终为1。我想为D中的每个键创建范围,如下所示:

  • 第一个关键字:(0, D[FirstKey])

  • (SecondRangeParameterOfFirstKey, SecondRangeParameterOfFirstKey + ValueOfSecondKey)的第二个键(0.25,0.50)

  • 第三个关键字为( SecondRangeParameterOfSecondKey,SecondRangeParameterOfSecondKey + ValueOfSecondKey) (0.50,0.75)

  • 第四个键的范围是(0.75,1)

有一点是最后一个键的范围的最后一个参数将始终为1,它是所有值的总和。

我在0和1之间生成一个随机浮点数。我需要在随机浮点数后返回键。因此,例如,对于字典D的给定顺序,如果我生成0.63,那么我必须返回G的第三个键,因为它的范围是(0.50,0.75)。由于字典没有排序所以我必须按照字典的顺序计算范围并返回按字典顺序返回密钥。到目前为止,我编写了这个问题如下:

import random
def W(D):
    vv = 0
    f = 0
    mer = ''
    ran = random.uniform(0,1)
    DI = D.items()
    for k,v in DI:
        mer = ''
        if (ran >= f) and (ran < D[k]+vv):
            mer = k
            vv += v
return mer

当生成的浮点数落在第三个键范围(0.50,0.75)时,我的函数永远不会返回第三个键,而是返回第四个键。

1 个答案:

答案 0 :(得分:1)

Dicts是无序的,所以如果你想要维护一些订单,你将需要一个OrderedDict,这将根据关键顺序增加范围找到该范围内的密钥,这要求你添加按值排序的密钥:

from collections import OrderedDict
od = OrderedDict((('A', 0.25), ('C', 0.25), ('G',0.25), ('T', 0.25)))

def W(od):
    ran = random.uniform(0, 1)
    tot = 0
    for k, v in od.items():
        if tot <= ran < v + tot:
            return k
        tot += v

在循环中添加print(ran, v, tot + v)

In [36]: W(od)
0.13237220509287917 0.25 0.25
Out[36]: 'A'

In [37]: W(od)
0.22239648741773488 0.25 0.25
Out[37]: 'A'

In [38]: W(od)
0.2798873944681526 0.25 0.25
0.2798873944681526 0.25 0.5
Out[38]: 'C'

In [39]: W(od)
0.05933372630532163 0.25 0.25
Out[39]: 'A'

In [40]: W(od)
0.776438095223963 0.25 0.25
0.776438095223963 0.25 0.5
0.776438095223963 0.25 0.75
0.776438095223963 0.25 1.0
Out[40]: 'T'

如果值不是全部相同,则需要排序,您可以使用operator.itemgetter作为键按值对项目进行排序:

from operator import itemgetter
d = {'A': 0.35, 'C': 0.2, 'T': 0.3, 'G': 0.15}

def W(d):
    ran = random.uniform(0, 1)
    tot = 0
    # sort from lowest value to highest
    for k, v in sorted(d.items(),key=itemgetter(1)):
        if tot <= ran < v + tot:
            return k
        tot += v

再次添加打印件:

In [55]: W(d)
0.15 0.24005200696606188 0.15
0.2 0.24005200696606188 0.35
Out[55]: 'C'

In [56]: W(d)
0.15 0.9860872247496385 0.15
0.2 0.9860872247496385 0.35
0.3 0.9860872247496385 0.6499999999999999
0.35 0.9860872247496385 0.9999999999999999
Out[56]: 'A'

In [57]: W(d)
0.15 0.5690026436736583 0.15
0.2 0.5690026436736583 0.35
0.3 0.5690026436736583 0.6499999999999999
Out[57]: 'T'

In [58]: W(d)
0.15 0.28507671431234327 0.15
0.2 0.28507671431234327 0.35
Out[58]: 'C'