我正在尝试使用random模块生成(伪)随机数。我需要生成的数字在范围上不要太接近。例如,如果生成数字n,则另一个数字x不能为n + -5。
from random import randint
i = 10
j_list = []
k_list = []
while i != 0:
j = randint(-10, 10)
k = randint(-15, 15)
j_list.append(j)
k_list.append(k)
i -= 1
print("J list is: {} and K list is {}".format(j_list, k_list))
例如,当我上次运行它时,得到以下输出:
J list is: [-4, 5, 2, -3, 7, -4, 3, -1, -1, -6] and K list is [10, 3, -7, -1, -5, -11, 3, 8, 1, -7]
如您所见,j_list的第1个元素和第3个元素(即j_list [1:3])在+5之内。这不是我想要的;我希望列表中的每个元素都产生超出特定范围的值。
有什么办法吗?
答案 0 :(得分:2)
首先,在这里使用for循环比使用while循环更好:
# One line and you know the loop range immediately
for i in range(10):
print(i)
# Three lines and takes the reader two seconds to comprehend
i = 10
while i != 0:
i -= 1
print(i)
现在回答您的问题,您可以使用random.choice排除范围(j-5,j + 5):
from random import randint, choice
j_list = []
k_list = []
for i in range(10):
j = randint(-10, 10)
k = choice([n for n in range(-15, 15) if n not in range(j - 5, j + 6)])
j_list.append(j)
k_list.append(k)
print("J list is: {} and K list is {}".format(j_list, k_list))
如果只想使用randint,另一种方法是使用while循环保持重新滚动值k,直到它不落在j + -5范围内:
from random import randint
j_list = []
k_list = []
for i in range(10):
j = randint(-10, 10)
k = randint(-15, 15)
while abs(j - k) <= 5:
k = randint(-15, 15)
j_list.append(j)
k_list.append(k)
print("J list is: {} and K list is {}".format(j_list, k_list))
正如@ShadowRanger指出的那样,while循环策略对计算的要求较低,并且更易于阅读,因此您可能想要这样做。
答案 1 :(得分:0)
这里最好的解决方案不是过滤掉不良值,而是首先防止它们发生。一个简单的解决方案是生成一个更严格的数字范围(与整个范围一样大,减去要排除的数字),然后如果结果等于或大于结果的底数,则将省略数字的大小添加到结果中排除范围。
from random import randint
i = 10
j_list = []
k_list = []
too_close = 5
while i != 0:
j = randint(-10, 10)
k = randint(-15, 15 - (too_close * 2 + 1)) # excluding j +- 5 means 11 numbers we won't use
# The range from j - 5 to 4 is logically j + 6 to 15, so when we
# generate a number of j - 5 or higher, we add 11 to adjust it to the desired result
if k >= j - too_close:
k += too_close * 2 + 1
j_list.append(j)
k_list.append(k)
i -= 1
print("J list is: {} and K list is {}".format(j_list, k_list))
对于任何复杂程度的PRNG,这都应该在性能上取胜,因为这意味着您永远不会生成任何个随机数;因为您确保直接生成有效数字,所以没有“测试不良并生成新循环”之类的信息。
旁注:
i = 10
while i != 0:
...
i -= 1
否则i
未被使用是一种毫无意义的复杂拼写方式:
for i in range(10):
...
或者如果我必须从10降到0:
for i in range(10, 0, -1):
...
for
的性能将胜过while
,并且错误发生的可能性大大降低(不能忘记调整i
或通过continue
等跳过调整步骤) )。
答案 2 :(得分:-1)
如何遵循这些思路,您可以轻松更改iterations
的数量,randint
的范围以及randint
之间的允许空间
from random import randint
def not_within_five(lista):
i = 0
while i < 10:
x = randint(0, 50)
if lista[i] in range(x-5, x+5):
continue
else:
lista.append(x)
i += 1
j = []
k = []
j.append(randint(0, 50))
k.append(randint(0, 50))
not_within_five(j)
not_within_five(k)
print(f"J list is {j}\n")
print(f"K list is {k}")
输出
(xenial)vash@localhost:~/python$ python3.7 randi.py J list is [19, 31, 49, 3, 9, 42, 29, 41, 22, 0, 35] K list is [42, 19, 13, 27, 42, 1, 26, 10, 17, 40, 47]