我在从(a,b)的不同集合生成X量的随机整数时遇到了困惑。例如,我想生成来自(1,5),(9,15)和(21,27)的5个随机整数。我的代码生成5个随机整数,但只有21到27之间,而不是其他两个。理想情况下,我希望看到1,4,13,22,25而不是21,21,25,24,27。
我的代码:
from random import randint
n = 0
while n < 5:
n += 1
for i in (randint(1,5),randint(9,15),randint(21,27)):
x = i
print i
答案 0 :(得分:8)
不理想
from random import randint, choice
for _ in range(5):
print(choice([randint(1,5),randint(9,15),randint(21,27)]))
正如Blender所说 - 更清晰的版本
from random import randint, choice
for _ in range(5):
r = choice([(1,5),(9,15),(21,27)])
print(randint(*r))
答案 1 :(得分:2)
你好!
这是一个有趣的问题;当你意识到要实现真正的随机性时,选择一个特定范围的概率必须用该范围的长度来衡量。
如果三个范围具有相等的长度,例如范围(0,10),范围(20,30)和范围(40,50);然后,要选择一个随机数,我们可以执行以下操作:
现在,考虑三个不等大小的范围,例如范围(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]
>>>
randomPicker
的另一个好处是它可以处理任意数量的范围。
希望这会有所帮助。
答案 2 :(得分:1)
<form method="post" enctype="multipart/form-data" ng-controller="commentCtrl" name="form">
<a href="" type="file" class="custom-height"><img src="source/assets/images/icons/icofileattached.png" class="attachmentpng-height" ngf-select="uploadFiles($file)" ng-model="files"/></a>
<md-button type="submit" class="md-raised custom-submit-button" ng-click="MakeComments()"> SUBMIT </md-button>
</form>
这个foor循环将从提供的第一个范围生成一个随机数,另一个用于第二个范围,最后一个用于最后一个范围,并在输出上打印每一个。 您的打印不在foor循环中,只打印最后一个范围内的最后一个随机数。
答案 3 :(得分:0)
表示非重复数字:
from random import randint, choice
randoms = []
counter = 0
while True:
new_random = (choice([randint(1,5),randint(9,15),randint(21,27)]))
if new_random not in randoms:
randoms.append(new_random)
counter += 1
if counter == 5 :
break
print randoms
答案 4 :(得分:0)
这里有一些有趣的答案,但我认为这个问题可以通过少量代码解决,即使它的可读性稍差。
这里的基本思想是你有一个固定数量的选择,所以你基本上可以有一个范围来完成这项工作,然后将结果绘制到你想要的范围。或者,如果您想以另一种方式考虑它,请创建一个函数f(x) -> y
,归结为同样的事情。
from random import randint
for i in xrange(5):
n = randint(1,19)
if n > 12:
print(n + 8)
elif n > 5:
print(n + 3)
else:
print(n)
或者,有一个功能:
from random import randint
def plot_to_ranges(n):
if n > 12:
return n + 8
elif n > 5:
return n + 3
else:
return n
for i in xrange(5):
n = randint(1,19)
print(plot_to_ranges(n))
如果您使用的是Python 3.x,则应将xrange
更改为range
。
答案 5 :(得分:0)
import itertools, random
nums = list(itertools.chain(
range(1,5),
range(9,15),
range(21,27)))
random.choices(nums, k=5)
答案 6 :(得分:0)
Sumukh Barve 回答的补充:
策略 3:在不串联范围的情况下选择范围的成员
此方法对指定范围的长度求和。然后它产生一个在该范围内的随机整数。然后它根据它相对于范围的位置添加到该整数。
示例: 如果范围是 (1,3) 和 (5,9),则范围包括在内。将所有范围的长度相加得到 3+4=7。然后我们创建一个介于 1 到 7(或 0 到 6)之间的随机整数。假设我们得到 2,我们从第一个范围中选择第二个项目。如果我们得到 5,我们从第二个范围中选择第二个项目。
def randint_within_ranges(ranges):
"""ranges is a list of tuples, where each tuple is a range. E.g. [(0, 2), (4, 6), (10, 100)].
Ranges must be non-overlapping.
Ranges are inclusive (e.g. can return 4 or 6).
Returns a random int anywhere in any of those ranges.
(In this example, high probability will be from (10,100) range.)
"""
#in case ranges aren't ordered, sort them now. Lowest first, e.g. [(0, 2), (4, 6), (10, 100)]
ranges = sorted(ranges, key=min)
#print('ranges',ranges)
total_range_size = sum([abs(range_[1]-range_[0])+1 for range_ in ranges])
#print('total_range_size',total_range_size)
lowest_range_start = min([min(range_) for range_ in ranges])
#print('lowest_range_start',lowest_range_start)
randint = random.randint(0, total_range_size-1)
#print('randint',randint)
randint += lowest_range_start
#print('randint',randint)
#add the gaps
for i in range(len(ranges)-1):
if randint > max(ranges[i]):
randint += (min(ranges[i+1])-max(ranges[i])-1)#gaps[i]
return randint
print( randint_within_ranges([ (4, 6), (-300, -290), (285,289), (10, 15), (48,53), (85,91)]) )
您可以使用以下方法测试这仅返回范围内的数字。范围包括两个边界。
randints = set()
for i in range(1000):
randints.add(randint_within_ranges([ (4, 6), (-300, -290), (285,289), (10, 15), (48,53), (85,91)]))
print(len(randints), sorted(list(randints)))