这是一个有趣的问题,当你意识到要实现真正的随机性时,选择特定范围的概率必须根据该范围的长度加权,这使得它变得更加有趣。
等长的范围:
如果三个范围长度相等,比如范围(0,10),范围(20,30)和范围(40,50);那么,为了选择一个单一的随机数,我们可以采取以下步骤:
1. 随机选择一个范围。
2. 从该范围内随机选择一个数字。
不等长的范围:
现在,考虑三个不等长的范围,例如范围(0, 2),范围(4, 6)和范围(10, 100);
第三个范围比前两个范围要大得多。如果我们采用与处理等长范围相同的策略,我们会偏向于从前两个范围中选择数字。
为了从三个不等长的范围中选择真正的随机数,有两种策略。
策略1:使用概率
选择范围的概率应该使得选择数字的概率保持不变。我们可以通过降低选择较短范围的概率来实现这一点。
然而,除了计算概率权重之外,还有一种更好的解决方案。请参见策略2。
策略2:合并范围
我们可以将三个范围简单地合并成一个范围。然后,从合并的范围中随机选择一个数字。这很简单:
import random;
def randomPicker(howMany, *ranges):
mergedRange = reduce(lambda a, b: a + b, ranges);
ans = [];
for i in range(howMany):
ans.append(random.choice(mergedRange));
return ans;
让我们看看它的实际效果:
>>> randomPicker(5, range(0, 10), range(15, 20), range(40, 60));
[47, 50, 4, 50, 16]
>>> randomPicker(5, range(0, 10), range(70, 90), range(40, 60));
[0, 9, 55, 46, 44]
>>> randomPicker(5, range(0, 10), range(40, 60));
[50, 43, 7, 42, 4]
>>>
< p >
randomPicker
的另一个好处是可以处理任意数量的范围。
random.randint(*random.choice([(1, 5), (9, 15), (21, 27)]))
这段代码稍微清晰了一些。 - Blender