【问题标题】:For loop, repetitive calculation in Pythonfor循环,Python中的重复计算
【发布时间】:2012-05-15 22:30:28
【问题描述】:
from random import uniform

prob = [0.25,0.30,0.45]

def onetrial(prob):
    u=uniform(0,1)
    if 0 < u <= prob[0]:
        return 11
    if prob[0] < u <= prob[0]+prob[1]:
        return 23
    if prob[0]+prob[1] < u <= prob[0]+prob[1]+prob[2]:
        return 39

print onetrial(prob)

我想知道如何使用一些 for 循环技术来减少 def 中的重复部分。谢谢。

【问题讨论】:

  • 看起来像是某种类型的轮盘赌选择.. 我不认为代码是不清楚的,prob 会变大还是变化?我只是好奇这样做的动机 - 谢谢
  • 你不需要测试&lt;部分(由前面的if处理)。
  • 如果您假设概率总和为 1.0,您可以完全跳过最后一个 if。如果舍入导致您错过最后一个条件并跑出函数的末尾,这也会更安全。
  • 虽然它变得凌乱并且可能不是你所要求的,但它可以作为一个疯狂的单线器来完成(可以分成可理解的位),因为你有u[11,23,39][map(lambda x: u&lt;=x, [sum(prob[0:i+1]) for i in xrange(len(prob))]).index(True)]
  • 谢谢大家。 @Levon,代码是用概率质量函数(prob)生成一个随机变量X。

标签: python for-loop repeat


【解决方案1】:

以下代码等同于您当前的代码,它使用 for 循环:

from random import uniform

prob = [0.25, 0.30, 0.45]

def onetrial(prob):
    u = uniform(0, 1)
    return_values = [11, 23, 39]
    total_prob = 0
    for i in range(3):
        total_prob += prob[i]
        if u <= total_prob:
            return return_values[i]

我有点不清楚您返回的值与概率之间的关系,您的代码 prob 似乎总是正好有 3 个元素,所以我也做了这个假设。

【讨论】:

    【解决方案2】:

    我喜欢 F.J 的回答,但我会使用元组列表,假设您可以轻松做到这一点:

    from random import uniform
    
    prob = [(0.25, 11), (0.30, 23), (0.45, 39)]
    
    def onetrial(prob):
        u = uniform(0, 1)
        total_prob = 0
        for i in range(3):
            total_prob += prob[i][0]
            if u <= total_prob:
                return prob[i][1]
    

    【讨论】:

      【解决方案3】:

      假设您经常调用onetrial,请先计算CDF,使其更快一点:

      from random import uniform
      
      vals = [11, 23, 39]
      prob = [0.25, 0.30, 0.45]
      cdf = [sum(prob[0:i+1]) for i in xrange(3)]
      
      def onetrial(vals, cdf):
          u = uniform(0, 1)
          for i in range(3):
              if u <= cdf[i]:
                  return vals[i]
      

      您可以使用bisect 使其更快。

      【讨论】:

      • 为什么函数中有prob?
      • 这条线def onetrial(prob):应该是def onetrial(cdf, vals):我认为
      猜你喜欢
      • 2010-11-14
      • 2018-06-29
      • 2020-10-18
      • 2017-02-12
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      相关资源
      最近更新 更多