【问题标题】:How do you create a random range, but exclude a specific number?如何创建随机范围,但排除特定数字?
【发布时间】:2015-07-02 20:42:11
【问题描述】:

我有以下代码:

while True:
    if var_p1 != "0":
        break
    else:
        import random
        var_p1 = random.randint(-5,5)

我希望循环重复直到var_p1 等于除零以外的任何值。但是,我总是得到零。我做错了什么?

【问题讨论】:

  • 你了解 "0" 和 0 之间的区别吗?至少在 Python 中?
  • 不是真的......我一直在慢慢地使用在线教程等自学。但是我不记得正确解释了差异......
  • 嗯。我认为这部分留给用户理解。无论如何记住这一点,单/双引号内的任何内容都是python中的字符串。例如:x =“1234”是一个字符串(不是整数/数字),但x = 1234是整数值(数字)。如果您还不清楚,那么我会进一步解释。

标签: python if-statement random while-loop range


【解决方案1】:

"0" != 0.

您正在与一个字符串进行比较,但randint 给您一个整数。

【讨论】:

    【解决方案2】:

    你检查一个字符串来打破循环。所以使用:

    if var_p1 != 0:
    

    代替:

    if var_p1 != "0":
    

    a 生成到b 但不包括值c 的内存有效方法是:

    r = random.randint(a, b - 1)
    if r >= c:
        r += 1 
    

    这样,在第一步中,我们将在ac - 1 之间或cb - 1 之间生成一个随机整数。在第二种情况下,我们加一,得到一个介于c + 1b 之间的随机数。很容易看出a..(c - 1)(c + 1)..b之间的每个数字都有相同的概率。

    【讨论】:

    • 会建议这种方法,但我认为使用 choice 更好,因为它避免了 if... 但 Moose 击败我提交了答案. :)
    • 确实,正如我在 Moose 回答的评论中提到的那样,如果您在生成随机数的函数中本地创建它,那是非常浪费的。通常,我会在全局上下文中创建它(作为元组),就在随机化函数定义的上方。
    • @JuniorCompressor 我猜选择的优点是每个元素都以相同的概率绘制。令人恼火的是,文档没有说明这一点。
    • @moose 是的,两种方法都给出相同的概率。我认为当您的数据不遵循模式并且您对空间没有问题时,选择肯定是非常好的。否则,您最终可能会存储一百万个整数来选择一个随机整数,因为您只需要一个异常。
    【解决方案3】:

    您的代码失败,因为您将整数与字符串进行比较。您的代码还有其他问题:

    • 循环中有一个import 语句。
    • 不知道您的循环将运行多少次。

    这是一种无循环的方法,可以随机生成从 -5 到 +5 的非零整数。

    import random
    x = random.randint(1, 5)
    if random.randrange(2) == 1:
      x = -x
    

    此代码保证调用random.randrange 两次。

    【讨论】:

    • 感谢您提到import 应该在脚本的顶部。将其放入循环本身并不是错误,随后尝试导入同一模块将没有效果,但它的风格仍然很差。
    • 是的,没有办法知道 OP 代码中的循环将运行多少次。但是,预期值是每个返回的数字 1.1 个循环,即返回 1000 个数字通常会生成 1100 个随机数。因此,尽管 OP 的算法的运行时间是不确定的,但实际上并没有那么糟糕,因为您的算法和 JuniorCompressor 都需要生成 2000 个随机数才能返回 1000 个结果。
    • 是的,你是对的。 1.1 的预期值优于 2 的保证值。
    • 亲爱的未来人士:JuniorCompressor 的代码已更改,因此我之前的评论不再适用。 :)
    【解决方案4】:

    回答标题中的问题,而不是真正的问题(由 Daniel Roseman 回答):

    如何创建随机范围,但排除特定数字?

    使用random.choice:

    import random
    allowed_values = list(range(-5, 5+1))
    allowed_values.remove(0)
    
    # can be anything in {-5, ..., 5} \ {0}:
    random_value = random.choice(allowed_values)  
    

    【讨论】:

    • 我看不到 5 之后 +1 的原因。为什么你不能使用 (-5,5) ?
    • 您需要range(5,6),因为范围确实排除了右边界。见range
    • 此代码对random 函数进行了最佳调用次数,因此它(可能)是最有效的,假设allowed_values 不会在循环中生成(例如,如果它是在随机化函数中作为局部变量生成)。
    【解决方案5】:

    作为一种替代方法,只需从数组中选择一个随机元素 [-5, -4, -3, -2, -1, 1, 2, 3, 4, 5]。保证只需一个电话即可工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      相关资源
      最近更新 更多