我想在任何提供的范围内只创建一个随机素数。我有这段代码:
print [x for x in range(5000, 5200)
if not [t for t in range(2, x)
if not x % t]]
但我的程序提供了一组素数。我想修改我的代码并在任何提供的范围内只创建一个随机数,但我找不到如何做。 请帮助。
答案 0 :(得分:3)
我对mathmax的解决方案的问题在于它完成所有工作以找到5000到5200之间的素数只是为了选择一个并抛弃其余的。在您找到第一个属于素数的第一个之前,随机选择5000到5200之间的唯一数字可能更有效:
import random
minimum = 5000
maximum = 5200
next((x for x in random.sample(range(minimum, maximum), maximum - minimum) if not [t for t in range(2, x) if not x % t]), None)
这大约快了18倍。通过对我们的素性测试更加智慧,我们可以获得18倍的改进:
next((x for x in random.sample(range(minimum, maximum), maximum - minimum) if not [t for t in [2] + list(range(3, int(x**0.5) + 1, 2)) if not x % t]), None)
请注意,random.sample()
用于返回与random.shuffle()
不同的结果,该结果在列表中运行。如果您更喜欢random.shuffle()
,并且不在表达式中包含两次数字,则可以执行以下操作:
next((x for x in (lambda y: random.shuffle(y) or y)(list(range(5000, 5200))) if not [t for t in range(2, x) if not x % t]), None)
答案 1 :(得分:2)
方法1:
import random
random.choice([x for x in range(5000, 5200) if not [t for t in range(2, x) if not x % t]])
实际上你几乎就在那里,你只需要使用random.choice()
方法2:
否则,您可以使用permutation
随机置换素数范围,然后选择第一个元素:
import numpy as np
np.random.permutation([x for x in range(5000, 5200) if not [t for t in range(2, x) if not x % t]])[0]
答案 2 :(得分:2)
这是迈向更有效解决方案的一步。不是根据所有可能的除数来测试每个素数的数量,而是保留一个预先生成的素数列表。
接下来,当我们准备在范围内选择随机素数时,我们使用二分法有效地找到所有有效答案的列表并随机选择一个。如果此类列表为空,请返回None
。
from __future__ import print_function
import bisect
import random
from itertools import takewhile
class Primes(object):
def __init__(self):
self.primes = [2, 3]
self.candidate = 5
def process_candidate(self):
if all(self.candidate % p != 0 for p in takewhile(
lambda x: x * x <= self.candidate, self.primes)):
self.primes.append(self.candidate)
self.candidate += 2
def maybe_random_prime_from_range(self, a, b):
if b < a:
return None
while self.candidate < b:
self.process_candidate()
ai = bisect.bisect(self.primes, a)
bi = bisect.bisect(self.primes[ai:], b)
try:
return random.choice(self.primes[ai:ai+bi])
except:
return None
ps = Primes()
print(ps.maybe_random_prime_from_range(4000, 4200))
答案 3 :(得分:1)
你的程序几乎是正确的,只需随机选择即可。但是我可以指出它浪费了很多时间。我以有效的方式写了同样的内容
import random
from math import sqrt
def prime(x):
if x%2==0:return False
elif any(x%i==0 for i in xrange(3,int(sqrt(x))+1,2)):return False
else:return True
prime_list=[x for x in xrange(5000,5200) if prime(x)]
print random.choice(prime_list)