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

3
我有以下代码:

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

我希望循环重复直到var_p1不等于零。但是我一直得到零。我做错了什么?


2
你理解“0”和0之间的区别吗?至少在Python中是这样吗? - d-coder
并不是这样的...我一直在通过在线教程等自学。然而,我不记得有人正确地解释过这个区别... - ShaunNZ
嗯,我认为这部分留给用户自己理解。无论如何,请记住,在Python中,任何单引号/双引号内的内容都是字符串。例如:x =“1234”是一个字符串(不是整数/数字),但x = 1234是整数值(数字)。如果您还不清楚,那么我将用更详细的解释来回答。 - d-coder
5个回答

10

回答标题中的问题,而不是真正的问题(该问题已由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)? - ShaunNZ
你需要使用range(5,6),因为range函数不包括右边界。请参考range - Martin Thoma
这段代码对random函数进行了最优数量的调用,因此它是(可能)最有效的,假设allowed_values不会在循环中生成(例如,如果它作为随机器函数中的局部变量生成)。 - PM 2Ring

5

"0" != 0.

你正在比较一个字符串,但是randint给你的是一个整数。


4

你可以使用字符串来检查并中断循环。因此,请使用以下代码:

if var_p1 != 0:

替代:

if var_p1 != "0":

一种内存占用较少的方法是,生成从ab但不包括值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 在提交答案方面比我更快。 :) - PM 2Ring
1
确实,正如我在Moose的答案评论中提到的那样,如果您在生成随机数的函数中本地创建它,那将非常浪费资源。通常,我会在全局上下文中创建它(作为元组),就在随机化函数定义的上面。 - PM 2Ring
@JuniorCompressor 我猜测 choice 的优点在于每个元素被选中的概率相同。令人不爽的是,文档没有明确说明这一点。 - Martin Thoma
1
@moose 是的,这两种方法都给出了相同的概率。我认为当你的数据不遵循一定模式且空间不是问题时,选择“choice”肯定是非常好的。否则,你可能会因为需要一个例外而存储一百万个整数来随机选择一个。 - JuniorCompressor

3

你的代码失败是因为你在比较一个整数和一个字符串。你的代码还存在其他问题:

  • 你在循环内部有一个import语句。
  • 无法确定你的循环会运行多少次。

这里提供了一种不需要循环的方法来随机生成一个从-5到+5(包括-5和+5)的非零整数。

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

这段代码保证了会恰好调用两次 random.randrange


感谢您提到import应该放在脚本的顶部。将其放在循环内部并不是错误,虽然后续尝试导入相同的模块将不会产生影响,但这仍然是不良的编程风格。 - PM 2Ring
是的,无法知道OP代码中的循环将运行多少次。但是,期望值为每个返回的数字1.1个循环,即要返回1000个数字,通常会生成1100个随机数。因此,尽管OP算法的运行时间是非确定性的,但实际上并不那么糟糕,因为您的算法和JuniorCompressor的算法都需要生成2000个随机数才能返回1000个结果。 - PM 2Ring
是的,你说得对。期望值为1.1比保证值为2更好。 - Michael Laszlo
亲爱的未来人们:JuniorCompressor的代码已经改变,所以我的先前评论不再适用于它。 :) - PM 2Ring

0
作为另一种方法,只需从数组[-5,-4,-3,-2,-1,1,2,3,4,5]中随机选择一个元素。保证只需一个调用即可正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接