按给定间隔打印素数的反向列表

时间:2018-10-07 18:44:50

标签: python

所以我想出了如何在给定间隔内以相反的形式打印所有素数,但是对于一个测试用例,当他们将下限设置为1时,它也会打印出来。我们知道1不是质数。

我的代码是:

def prime_list_reversed(x, y):
"""
Input: the number x and y
Output: all prime numbers within [x,y] in reverse order

>>> prime_list_reversed(3, 10)
[7, 5, 3]
>>> prime_list_reversed(3, 3)
[3]
>>> prime_list_reversed(2, 2)
[2]
"""
assert type(x) == int, "first argument must be an integer"
assert type(y) == int, "second argument must be an integer"
assert x > 1, "1 is not a prime number"
assert y >= x,  "second argument must be >= the first one"

# YOUR CODE IS HERE #
lst = []
for i in range(x, y + 1):
    for c in range(2, i):
        if (i % c) == 0:
            break
    else:
        lst.append(i)
return list(reversed(lst))

一个测试用例

prime_list_reversed(1, 3)
[3,2,1]

1 个答案:

答案 0 :(得分:2)

您的素数检查器将为i=1构造range(2, 1),但是该范围为 empty 。确实:

>>> list(range(2, 1))
[]

所以这意味着对i=1进行了 no 检查,因此您的程序将其视为素数号。我们可以在这里做两件事:

  1. 使用if的{​​{1}}语句进行检查,以免产生辐射;
  2. 确保外部范围永远不会发射i == 1
1

上面的方法解决了这个问题,但不是很优雅:我们首先构造一个列表,然后反转该列表。我们也可以简单地反向发出元素:

def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(max(2, x), y + 1):
        for c in range(2, i):
            if (i % c) == 0:
                break
        else:
            lst.append(i)
    return list(reversed(lst))

现在,我们因此产生相反的元素。但是代码仍然效率低下:我们测试所有偶数。但是测试一个数字是否可以除以def prime_list_reversed(x, y): # ... lst = [] for i in range(y, max(2, x) - 1, -1): for c in range(2, i): if (i % c) == 0: break else: lst.append(i) return lst就足够了,如果不能,我们可以省略对24等的检查,因为如果不能除以{{ 1}},它绝对不能被62除。而不是检查数字是否可以被4

整除
6

但是它仍然可以更有效。如果将数字 a 除以 b ,我们知道存在一个 c = a / b 。这意味着如果 b>√a,则c≤√a。我们可以利用此属性:检查√i就足够了,因为我们知道否则我们已经通过其他部门进行了测试:

2

最后,通常最好将其生成为发电机,因为这可以让我们懒惰例如采用前10个元素:

def prime_list_reversed(x, y):
    # ...
    lst = []
    for i in range(y - (~y & 1), max(3, x) - 1, -2):
        for c in range(3, i, 2):
            if (i % c) == 0:
                break
        else:
            lst.append(i)
    if x <= 2 < y:
        lst.append(2)
    return lst

然后我们获得from math import ceil, sqrt def prime_list_reversed(x, y): # ... lst = [] for i in range(y - (~y & 1), max(3, x) - 1, -2): for c in range(3, ceil(sqrt(i))+1, 2): if not i % c: break else: lst.append(i) if x <= 2 < y: lst.append(2) return lstfrom math import ceil, sqrt def prime_list_reversed(x, y): # ... for i in range(y - (~y & 1), max(3, x) - 1, -2): for c in range(3, ceil(sqrt(i))+1, 2): if not i % c: break else: yield i if x <= 2 < y: yield 2之间的范围:

1