【问题标题】:Python Dictionary, make range associated with its values and return themPython字典,使范围与其值相关联并返回它们
【发布时间】:2016-05-23 21:07:59
【问题描述】:

说,我有一本字典

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

字典值的总和总是一。我想为 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) 的浮点数时,我的函数永远不会返回第三个键,而是返回第四个键。

【问题讨论】:

  • 你只生成一个随机数?字典也是无序的,因此除非您对数据进行排序,否则不知道第一个键
  • 每次运行这个函数,我只生成一个随机浮点数。
  • 那么你想要随机浮点值下最接近的值吗?为什么这些值没有存储为上限,您对第一个键的想法是什么?
  • 我听不懂你的话。
  • 什么是第一把钥匙?它是否基于值、键.. 值是否总是相等的,即如果你有 10 个键,那么所有的键都是 0.10?你说 对于字典 D 的给定顺序 但是字典是无序的,所以没有意义

标签: python-3.x


【解决方案1】:

字典是无序的,所以如果你想保持一些顺序,你需要一个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作为key来按值排序:

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'

【讨论】:

  • 感谢您对我的问题的友好关注。你几乎是我所期望的,但我只需要从 0 开始 v,第一次迭代为 0,第二次迭代为 0.25,第三次迭代为 0.50,最后一次为 0.75。我不想在这里相乘,而是在第二次迭代时 v 的值将是第一次迭代的 tot+v 值,第三次 v 将是第二次迭代的 tot+v 的值,所以 v 是 0.50,最后会为 0.75
  • @DumbCoder,这里没有乘法,我们所做的只是将总和从最低值到最高值相加
  • 谢谢,你又救了我一天。它准确地返回了我想要的,但是在我需要应用这个函数的地方给出了错误的答案。我认为我误解了要求。
  • 谢谢,现在可以使用了。我需要了解集合和操作员模块。我认为这样的模块会节省我的时间。请给我一些关于它们的链接,我可以学到新的东西。
  • @DumbCoder,别担心,我添加了文档的链接
猜你喜欢
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
  • 2019-07-23
相关资源
最近更新 更多