首先,您需要一个好的素数检查器。 Wikipedia has an implementation -- 根据python版本等可能会进一步优化。
现在,列出所有素数的索引:
indices = [i for i, val in enumerate(data) if is_prime(val)]
接下来,选择一个任意数字并找到它的索引(或者不是任意...)。
n = random.choice(data)
idx = data.index(n)
我们就快到了...将您的方法一分为二,找出n 的索引在索引列表中的位置。
indices_idx = bisect.bisect_left(indices, idx)
现在,要确定更接近的数字是在左侧还是右侧,我们需要查看这些值。
# Some additional error handling needs to happen here to make sure that the index
# actually exists, but this'll work for stuff in the center of the list...
prime_idx_left = indices[indices_idx - 1]
prime_idx_right = indices[indices_idx]
最后,找出哪个索引更接近并提取值:
if (idx - prime_idx_left) <= (prime_idx_right - idx):
closest_prime = data[prime_idx_left]
else:
closest_prime = data[prime_idx_right]
请注意,我在假设您将一遍又一遍地使用相同的列表的情况下进行了此操作。如果你不是,你最好这样做:
- 找到您感兴趣的号码的索引。
- 找到右边第一个素数的索引(如果存在)
- 找到左边第一个素数的索引(如果存在)
- 检查哪个更近
例如
def find_idx_of_prime(lst, start_idx, stop_idx, dir):
for ix in xrange(start_idx, stop_idx, dir):
if is_prime(lst[ix]):
return ix
return dir*float('inf')
idx = data.index(number)
left_idx = find_idx_of_prime(data, idx, 0, -1)
right_idx = find_idx_of_prime(data, idx, len(data), 1)
prime_idx = left_idx if idx - left_idx < right_idx - idx else right_idx
prime_value = data[prime_idx] # raises TypeError if no primes are in the list.