假设我们有一个素数对的列表,你称之为L3,可能是这样的:L3 = [(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61),
(71, 73), (101, 103), (107, 109), (137, 139)]
然后我们要做的是取一对的第一个元素减去前一个元素对的最后一个元素。在
我们还希望累积这些值的列表,以便稍后我们可以看到在哪个索引处出现最大值。reduce函数对此很好。在
^{pr2}$
然后打印reduce(helper_to_subtract_pairs, L3, [0])
给予[3, 0, 4, 4, 10, 10, 16, 10, 28, 4, 28, 139]
第一个元素的出现是因为在对reduce的调用中,我们使用了一个起始值[0](因此第一个素数3导致3-0)。我们可以忽略这一点。最后一项139表示如果最后还有一对,则该数字将成为减法的一部分。但既然没有,我们也可以忽略这一点:In [336]: reduce(helper_to_subtract_pairs, L3, [0])[1:-1]
Out[336]: [0, 4, 4, 10, 10, 16, 10, 28, 4, 28]
现在,我们需要最大值出现的索引。为此,让我们使用argmax的Python方法:def argmax(some_list):
return max(enumerate(some_list), key=lambda x:x[1])[0]
然后我们得到:In [338]: argmax(reduce(helper_to_subtract_pairs, L3, [0])[1:-1])
Out[338]: 7
告诉我们指数7的差距是最大的(或者至少是并列最大的)。本例中的第7个间隙介于(101,103)和(71,73)之间(记住Python是基于0的,所以第7个间隙实际上是在第7对和第8对之间)。在
因此,作为列表L3的函数,我们可以写下:def max_gap(prime_list):
gaps = reduce(helper_to_subtract_pairs, prime_list, [0])[1:-1]
max_idx = argmax(gaps)
return gaps[max_idx], prime_list[max_idx:max_idx + 2]
整件事看起来像:def argmax(some_list):
return max(enumerate(some_list), key=lambda x:x[1])[0]
def helper_to_subtract_pairs(acc, x):
return acc[:-1] + [x[0] - acc[-1]] + [x[1]]
def max_gap(prime_list):
gaps = reduce(helper_to_subtract_pairs, prime_list, [0])[1:-1]
max_idx = argmax(gaps)
return gaps[max_idx], prime_list[max_idx:max_idx + 2]
L3 = [(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61),
(71, 73), (101, 103), (107, 109), (137, 139)]
print max_gap(L3)
哪个指纹In [342]: print max_gap(L3)
(28, [(71, 73), (101, 103)])
修改argmax以返回所有出现的max。如果这是为了研究间隙大小的渐近增长,则不需要这样做,因为任何max都会汇总一组特定的素数。在