Python素数列表

时间:2017-09-10 14:46:51

标签: python

我试图找出为什么这两个片段应该基本上做同样的工作,但不知何故他们没有。

我想找到1-100之间的素数。我知道这可行:

# This create an empty list first.
# if number qualifies the prime number then append, if not then break.

pnumber1 = []
for x in range(2, 101):
    for i in range(2, x):
        if x % i == 0:
            break
    else:
        pnumber1.append(x)
print(pnumber1)

所以我试图以另一种方式玩,我创建了一个包含所有数字1-100的列表,并删除不是素数的数字。然后剩下的应该是素数列表。所以我有:

# note: this code should exclude '2', which is a prime number, I'll worry about that later.

pnumber1b = list(range(3, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            pnumber1b.remove(x)
    else:
        break
print(pnumber1b)

不知何故,这不会起作用,因为它将从3到100返回每个数字。这意味着pumber1b.remove(x)无效。

好的,如果我这样试试:

  pnumber1b = list(range(3, 101))
    for x in pnumber1b:
        for i in range(2, x):
            if x % i == 0:
                pnumber1b.remove(x)
            else:
                break
print(pnumber1b)

要更改缩进级别,它仍会返回:list.remove(x): x not in list

4 个答案:

答案 0 :(得分:1)

有一些不明确的行为会使你的第一个代码工作,但第二个代码不会发生。

for循环如果设法在没有else的情况下自然完成,则会执行break语句。

打印“Ok!”:

for i in range(10):
    if i == 11: break  # Condition not reached, loop ends naturally
else:
    print('Ok!')

虽然这不是:

for i in range(10):
    if i == 5: break
else:
    print('Ok!')

如果像你一样,你这样做:

pnumber1b = list(range(3, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            pnumber1b.remove(x)
    else:
        break

然后它将自然地到达for i in range(2, x):的末尾,将触发else并突破外循环,而不检查大多数值。

您可以删除else

pnumber1b = list(range(3, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            pnumber1b.remove(x)
print(pnumber1b)

这会失败,因为对于具有多个倍数的数字,它会尝试删除该项两次并在找不到已删除的项时引发异常。

然后你可以添加一个中断来在找到第一个后停止查找倍数:

pnumber1b = list(range(3, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            pnumber1b.remove(x)
            break
print(pnumber1b)

工作,除了在迭代列表时删除列表项会导致迭代出现问题。你会看到它只会开始删除偶数。

根据你展示的第一个例子,有什么工作(但是有点无意义)是创建一个新列表,将非素数添加到该列表,然后迭代列表之后,删除它们:

to_remove = []
pnumber1b = list(range(3, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            to_remove.append(x)
            break
for r in to_remove:
    pnumber1b.remove(r)
print(pnumber1b)

答案 1 :(得分:1)

当然它不起作用:以i = 2,x = 6为例,6不是主要的ergo你删除它。

在i的下一次迭代中,i = 3你再次遇到x = 6,并尝试再次删除它!所以你得到错误:list.remove(x):x不在列表中。

当然也是最重要的注意事项:你无法改变你正在迭代的列表!当你从列表中删除项目x时,你的下一次迭代将无效,列表将被破坏!

尝试添加另一个,如果它询问x是否仍然在pnumber1b中:

pnumber1b = list(range(3, 101))
pnumber1a = list(range(3, 101))
for x in pnumber1b:
        for i in range(2, x):
                if x % i == 0:
                    if x in pnumber1a:
                        pnumber1a.remove(x)
                        break
                    else:
                        continue

print(pnumber1a)

或者只是在删除命令后添加break,因为不需要继续运行数字x。

pnumber1b = list(range(3, 101))
pnumber1a = list(range(3, 101))
for x in pnumber1b:
        for i in range(2, x):
                if x % i == 0:
                    pnumber1a.remove(x)
                    break
print(pnumber1a)

答案 2 :(得分:1)

@ ddor254

你的第一组代码不正确,它只会删除偶数。

我把它改为:

pnumber1b = list(range(2, 101))
pnumber1a = list(range(2, 101))
for x in pnumber1b:
    for i in range(2, x):
        if x % i == 0:
            if x in pnumber1a:
                pnumber1a.remove(x)
    else:
        continue
print(pnumber1a)

现在这将有效

答案 3 :(得分:1)

此方法要求您使用一些已知的素数值填充数组。您添加到列表中的素数越多,检查器就越准确。

我已经针对前168个素数而没有跳过一个节拍。我建议您获取自己的素数列表以对其进行测试,并在返回“True”时查看是否有任何返回“False”。

def isprime(n):
if n==0 or n==1: return False
testlist = [2,3,5,7,9,11]

grand = 0

for test in testlist:
    if n==test: return True
    elif n%test==0: return False
    else: grand += 1

if grand > 0: return True
else: return False

可以通过以下方式使用此功能:

primearr = []
for x in xrange(1, 1000000):
    if isprime(x) == True:
        primearr.append(x)

这段代码足够快,我可以在大约一两秒内运行前1000000个数字。现在,如果你想查看结果,那么最好将它们放入文本文档而不是将它们读出来(这可能会冻结或崩溃Python),如下所示:

with open('primelist.txt', 'a') as f:
    for prime in primearr:
        f.write('{},'.format(prime))

然后您可以检查安装Python的目录以查找文本文档,除非您在文件名中指定了一个目录,如下所示:

with open('C:\\Users\\yourname\\Desktop\\primelist.txt', 'a') as f:

修改

我知道这是一个死灵编辑,但我觉得这是必要的,因为我确实让它成功检查了第一个10,000,000素数,并使用相同的主要测试列表。

我从这个来源获得了第一批10,000,000个素数:http://www.primos.mat.br/2T_en.html

primelist = []
with open('first-ten-million-primes', 'r') as r:
primes = r.readlines()

for prime in primes:
    for num in prime.split('\t'):
        primelist.append(int(num))

testlist = [2,3,5,7,9,11]
success, failure = [], []

for prime in primelist:
    grand = 0
    for test in testlist:
        if prime % test == 0 and prime != test: grand += 1
    if grand > 0: failure.append(prime)
    else: success.append(prime)

print('Successes: {}\r\nFailures: {}'.format(len(success), len(failure)))

该输出返回:

Successes: 10000000
Failures: 0

这完全在Python 3.6.5 x64上。