使用列表推导生成素数列表

时间:2015-05-07 06:27:42

标签: python

我正在尝试创建一个小于或等于给定数字的所有素数的列表。我成功地使用了for循环。我试图使用python实现相同的列表理解。但我的输出有一些意想不到的值。

这是我的代码..

pr=[2]
pr+=[i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]

其中num是我从用户那里获得的数字。

的上述代码的输出
num=20 is this:  [2, 3, 5, 7, 9, 11, 13, 15, 17, 19]

我很困惑为什么输出中有9和15。我在这里做错了什么?

3 个答案:

答案 0 :(得分:4)

在您的整个列表理解完成之前,您的列表pr不会更新。这意味着您的列表只包含2,因此每个可分为2的数字不在列表中(如您所见)。每当找到新的素数时,都应该更新列表。

答案 1 :(得分:4)

它根本不起作用。列表推导是分开评估的,所以你可以这样想象:

"A"

在评估pr = [2] tmp = [i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]] pr += tmp 时,tmp仅包含pr,因此您只需检查一个数字是否可被2整除(即如果它是偶数)。这就是为什么你得到所有不均匀的数字。

你根本无法使用列表推导来解决这个问题>

†不是很好,但是很丑陋且非常黑客,通过滥用你可以在列表理解中调用函数:

2

这会滥用列表推导,并且基本上会为您添加到pr = [2] [pr.append(i) for i in xrange(3,num+1) if not [x for x in pr if i%x==0]] print(pr) # [2, 3, 5, 7, 11, 13, 17, 19] 的每个素数收集None值。所以它基本上就像你的正常for循环,除了我们不必要地在列表中收集pr值...所以你应该让自己使用换行符并使用正常的循环。

答案 2 :(得分:1)

这是因为pr += [...]的评估大致如下:

pr = [2]
tmp = [i for i in xrange(3,num+1) if not [x for x in pr if i%x==0]]
pr.extend(tmp) 

因此,在生成tmp时,pr的内容保持不变([2])。

我会选择这样的功能:

>>> import itertools
>>> def primes():
...     results = []
...     for i in itertools.count(2):
...         if all(i%x != 0 for x in results):
...             results.append(i)
...             yield i
...
# And then you can fetch first 10 primes
>>> list(itertools.islice(primes(), 10))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
# Or get primes smaller than X
>>> list(itertools.takewhile(lambda x: x < 50, primes()))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

请注意,使用all比创建数组和测试它是否为空更有效。