Eratosthenes的筛子循环不正确拉动元素

时间:2015-10-08 19:02:42

标签: python sieve-of-eratosthenes

我正在使用Sieve of Eratosthenes算法,该算法涉及从列表中提取第一个元素,将其添加到素数列表中,然后从原始列表中提取该数字的任意倍数(从2开始) ,追加2,删除2的所有倍数。然后到下一个号码。

我的循环(在2-10的列表中进行的测试运行)完成了它第一次应该做的事情,但是不是在下一次拉3,而是直接跳到5并且我&#39 ; m留下2,5和9的列表。这是我的代码。

list_before_primes = [num for num in range(2, usr_in + 1)]
print(list_before_primes)
list_o_primes = []

for element in list_before_primes:
    list_o_primes.append(element)
    for sub_element in list_before_primes:
            if sub_element % element == 0:
                list_before_primes.remove(sub_element)

print(list_o_primes)

2 个答案:

答案 0 :(得分:2)

由于您修改了循环内的list_before_primes,因此不应使用for element in list_before_primes:(如@Kevin所述)。

您可以使用while list_before_primes:代替并将第一项投放到element

这也将解决@Kashyap Maduri评论(因为元素将从列表中删除)。

顺便说一句,您可以使用list_before_primes = [num for num in range(2, usr_in + 1)]

简化list_before_primes = list(range(2, usr_in + 1))

答案 1 :(得分:0)

以下是算法的实现:

def sieve_of_eratosthenes(usr_in):
    #you don't need list comprehension in your implementation. You can do this:
    list_before_primes = range(2, usr_in + 1)
    print(list_before_primes)

    #makes a set of list_before_primes
    #funny things can happen when you modify and iterate over the list at the same time. 
    #it is better to make a copy and remove from it.
    list_o_primes = set(list_before_primes)

    for i,element in enumerate(list_before_primes):
        for sub_element in list_before_primes[i+1:]:
            if sub_element % element == 0:
                if sub_element in list_o_primes:
                    list_o_primes.remove(sub_element)

    print(list_o_primes)

if __name__ == '__main__':
    sieve_of_eratosthenes(10)