我有一个方法,需要从 st
和 ed
之间的范围中选择一个随机 float
val
>,但我只想包含其中一个端点。 (或者,换句话说,(st, ed]
或 [st, ed)
。)我当前的解决方案是:
import random
val = None
st, ed = 0, 360
## In application, what I want is an angle, but I've made it generic as an example.
while not (st <= val < ed): # which of st or ed to reject is up to you.
val = random.uniform(st, ed)
...但是有没有一种方法(通过参数或符号)告诉 random.uniform (或类似的函数)包含或排除一个端点或另一个端点?也许NumPy
有答案?
我知道在具有十三个精度位的 float 范围内获得两个等效值的几率基本上为零,但我想知道是否只是为了更好地理解工具本身。
最佳答案
从广义上讲,您的解决方案似乎是合理的。如果您的 RNG 提供的值范围大于您需要的范围,您将丢弃无效结果并继续计算。显然,如果您的无效范围太大,则存在永远运行下去的危险,但最终这可能是您必须做出的牺牲。
事实上,这就是 Python 生成随机值的方式。来自 random._randbelow()
:
k = n.bit_length() # don't use (n-1) here because n can be 1 r = getrandbits(k) # 0 <= r < 2**k while r >= n: r = getrandbits(k) return r
它不断生成低于 2**k
的随机整数,直到结果低于所需的 n
。就像您正在尝试做的那样。
也就是说,对于您的具体情况,您不需要这样做 - 担心浮点范围的端点有点徒劳。
首先,正如 @user2357112 指出的那样,考虑均匀分布的开放端点与封闭端点有点迂腐。在实数轴(或任何子集)上,随机选择端点的概率为 0。此外,对于 float ,情况会变得更糟,而不是更好。由于浮点无法精确表示所有实数,因此完全有可能(甚至很可能)您的任一端点都不存在,因此无论您指定的范围如何,都无法返回。
@EllaShar 有一个有趣的想法,但我不会在实践中推荐它。如果您确实需要精确控制边界,请坚持原来的解决方案,它更简单、更易读、更明确正确。
<小时/>顺便说一句,如果您有一个返回 [a, b)
范围内的数字的 RNG,并且您想要获取 (a, b]
范围内的数字>,您可以简单地否定您的范围,例如
-random.randrange(-b, -a)
关于python - 有没有办法为 random.uniform 设置开放和封闭端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709065/