简体   繁体   English

这段python代码是我想要的吗?

[英]Is this python code doing what I want it to do?

I have this code 我有这个代码

import random
b = 20
x = random.randrange(0,b)
y = random.randrange(0,b)
ab = 0
xc = 0

while ab != 10:
    if x != y:
        x = random.randrange(0,b)
        y = random.randrange(0,b)
        xc = xc + 1
    elif x == y:
        print ab
        print 'number of tries out of', b, ' : ', xc
        ab = ab + 1
        xc = 0
        y = 999999

it's essentially a stats program. 它本质上是一个统计程序。 I want to see out of 10 tries how many times a random number needs to be generated in order to match. 我想查看10次尝试中需要生成多少次随机数才能匹配。 So far the numbers i have been getting after running this program i get these values, i ran the program 5 times so that would be a total of 50 tries. 到目前为止,我在运行该程序后获得的数字都得到了这些值,我运行了5次该程序,因此总共进行了50次尝试。

9
26
6
1
5
109
5
42
12
63

All of those low numbers has led me to wondering if my program is just extremely lucky or if something is wrong my code. 所有这些低数字使我想知道我的程序是否非常幸运,或者我的代码有什么问题。 Thanks! 谢谢!

Note: is there a way i can get XC to add up after each while loop and when the while loop is true for it to show the total? 注意:有没有一种方法可以让XC在每个while循环后以及while循环为true时加起来以显示总数?

I'd say that you were somewhat unlucky. 我会说你有点倒霉。

The average there is 27.8. 平均为27.8。 But if you pick two numbers between 0 and 20, you'd expect them to match about 1/20 of the time, and hence you expect to wait about 20 times before you get a match. 但是,如果您选择两个介于0到20之间的数字,则期望它们匹配大约1/20的时间,因此,您希望等待大约20次才能获得匹配。

Check it with a larger number of iterations: 进行大量迭代检查:

#!/usr/bin/env python
import random

max_num = 20
x = random.randrange(0, max_num)
y = random.randrange(0, max_num)
tries = 0

i = 0
iterations = 1000
total_tries = 0
while i < iterations:
    if x != y:
        x = random.randrange(0, max_num)
        y = random.randrange(0, max_num)
        tries += 1
    else:
        print(i)
        print('number of tries out of %s : %s ' % (max_num, tries))
        total_tries += tries
        i += 1
        tries = 0
        y = -1

print("Average tries: %s" % (total_tries / iterations))

If I run this, I get ~20 every time. 如果我运行这个程序,每次都会得到20左右。

Note: This could be simplified to this: 注意:这可以简化为:

#!/usr/bin/env python
import random

max_num = 20
iterations = 1000
total_tries = 0

for i in range(iterations):
    print(i)

    tries = 0
    x = 0
    y = -1
    while x != y:
        x = random.randrange(0, max_num)
        y = random.randrange(0, max_num)
        tries += 1

    print('number of tries out of %s : %s ' % (max_num, tries))
    total_tries += tries
    i += 1
    tries = 0

print("Average tries: %s" % (total_tries / iterations))

Your logic is very strange. 你的逻辑很奇怪。

  • You don't want to use artificial sentinel values to break out of a loop. 您不想使用人工前哨值来打破循环。 Just explicitly break out of it. 只是明确地打破它。

  • You fundamentally have two loops: one to iterate over trials, and one to see how many attempts are needed in a given trial. 从根本上讲,您有两个循环:一个循环进行试验,另一个循环查看给定试验中需要进行多少次尝试。 Don't hide that structure. 不要隐藏那个结构。

  • Don't cover all the cases with if / else if . 不要用if / else if涵盖所有情况。 That's what else is for. 那就是else目的。

  • Within a loop, generate numbers before you test them, not after. 在循环中,请在测试之前(而不是之后)生成数字。 That way it's clearer what you're doing, and you don't need an extra generation step before the loop. 这样一来,您就可以清楚地知道自己在做什么,并且在循环之前不需要额外的生成步骤。 Similarly, re-initialize values within a loop at the top, rather than the bottom. 同样,在顶部而不是底部的循环中重新初始化值。

  • Use clear variable names. 使用明确的变量名。 When there isn't a meaningful variable name, avoid creating a variable. 如果没有有意义的变量名,请避免创建变量。 You don't actually need to set two variables to random.randrange(0, b) to compare the results. 您实际上不需要将两个变量设置为random.randrange(0, b)来比较结果。 OTOH, if you want to simplify the logic and avoid writing a seemingly weird comparison of random.randrange(0, b) to itself, then you can note (and should be able to prove, if you're interested enough in this kind of stuff to write a program) that you can arbitrarily select a target value and get the same results. OTOH,如果您想简化逻辑并避免对random.randrange(0, b)进行看似奇怪的比较,那么您可以注意(并且应该能够证明,如果您对此类型足够感兴趣的话)编写程序的东西),您可以任意选择目标值并获得相同的结果。 Also, use variables to name your arbitrarily selected numeric constants. 同样,使用变量来命名任意选择的数字常量。

  • You can use += in Python to update a variable. 您可以在Python中使用+=更新变量。

  • Use print formatting. 使用打印格式。


import random
range_size = 20
total = 0
iterations = 1000 # or however many

for trial in xrange(iterations):
    attempts = 0
    while random.randrange(0, range_size) != 0: attempts += 1
    print "Trial #{0}: Took {1} tries to match one of {2} numbers.".format(
        trial, attempts, range_size
    )
    total += attempts

print "Average trials: {0}".format(float(total) / iterations)

If you don't need the debugging information, we can make things even cleaner by using built-in functions to do the summation and looping logic for us: 如果您不需要调试信息,我们可以使用内置函数为我们做求和和循环逻辑,从而使事情变得更加干净:

from random import randrange
from itertools import *
range_size = 20
total = 0
iterations = 1000 # or however many

print "Average trials: {0}".format(sum(
    sum(takewhile(lambda x: randrange(0, range_size) != 0, repeat(1)))
    # I tested that way, but this is probably more logical
    # even if it's more verbose:
    # len(list(takewhile(
    #     lambda x: x != 0,
    #     imap(randrange, repeat(0), repeat(range_size))
    # )))
    # 'lambda x: x != 0' can also be spelled 'bool' in this context,
    # but explicit is better than implicit...
    for i in xrange(iterations)
) / float(iterations))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM