【问题标题】:How can this random python behaviour be explained?如何解释这种随机的 python 行为?
【发布时间】:2016-06-23 15:28:38
【问题描述】:

这个小脚本会在 0 和 1 之间生成一个随机浮点数,然后如果它小于“0.000111111111111”,它将打印“找到它”的消息

import random

value = 0.4 / 3600
print value

while True:
    rand = random.random()

    print "RAND IS: " + str(rand) + "----- VAL IS " + str(value)
    if rand < value:
        print "found it"

所以看起来脚本运行并且它实际上从未“找到它”,但是当我在 if 语句之前注释掉 print 语句时,即使 rand 值不小于值,命令行也会填充“找到它” .什么鬼?

【问题讨论】:

    标签: python python-2.7 random


    【解决方案1】:

    您的 while 循环设计为永远运行,因为 True 始终是 True。你永远不会跳出那个无限循环。即使它找到了值,它也只是打印它,因为你给 while 循环的条件仍然是 True。由于不能改变条件,所以需要添加break语句:

    while True:
        rand = random.random()
        print "RAND IS: " + str(rand) + "----- VAL IS " + str(value)
        if rand < value:
            print "found it"
            break
    

    【讨论】:

    • 谢谢,我想我要疯了
    【解决方案2】:

    您的程序确实找到了小于和大于“值”的数字,无论它是否将它们全部打印出来。只是输出,双向,让你感到困惑。这是因为:(a) 您的计算机比您想象的要快,只要它不需要打印任何东西; (b) 但是当它确实必须打印某些东西时,它会减慢到您可以实际看到打印输出经过的程度; (c) 成功“发现”之间的迭代次数比您预期的要多。

    为了演示以上所有内容,我编写了这个脚本:

    #! /usr/bin/python
    
    import time
    import random
    import csv
    import sys
    
    def how_long_until(v):
        n = 0
        start = time.clock()
        rng = random.random
        while True:
            n += 1
            if rng() < v: break
        stop = time.clock()
        return n, stop - start
    
    wr = csv.writer(sys.stdout, quoting=csv.QUOTE_MINIMAL)
    wr.writerow(("loops", "cpu.time"))
    
    value = 0.4 / 3600
    for _ in range(10000):
        wr.writerow(how_long_until(value))
    

    这会生成随机数,直到找到比您的“值”小一为止,然后它会写出循环迭代的次数和经过的 CPU 时间来找到它。它做了一万次。在我的旧电脑上,但不是那么旧的,这个程序需要 6 秒才能运行。

    然后我绘制了两者的直方图。首先,我们看一下循环数:

    您可以看到,虽然找到小于 0.4/3600 的随机数通常只需要几千次迭代,但它可能需要多达 80,000 次迭代!这就是为什么在您看来“找到它”从未被打印出来的原因。

    现在让我们看看经过的时间:

    它看起来与循环次数的直方图非常相似,但请注意 X 轴刻度。那是以 毫秒 为单位的时间。即使需要 80,000 次迭代才能找到下一个小于 0.4/3600 的数字,计算机也只需要 4 毫秒 即可完成这一壮举!这就是为什么当您注释掉每次迭代的打印输出时,在您看来“找到它”不断被打印出来。

    【讨论】:

    • 哇。喜欢分析,可能会偷走作者的部分。您在代码中添加了中断,如上所述,这是缺少的部分。
    • @Hashman 我不清楚(实际上仍然不清楚)OP 是否希望脚本在发现足够小的值时停止。 csv stdlib 模块被低估了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2012-03-16
    • 1970-01-01
    • 2013-08-26
    • 2019-06-02
    • 1970-01-01
    相关资源
    最近更新 更多