[英]Generating a list of prime numbers using list comprehension
我正在尝试创建所有小于或等于给定数字的质数的列表。 我使用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感到困惑。 我在这里做错了什么?
这样根本行不通。 列表推导是单独评估的,因此可以像这样想象:
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]
此滥用列表理解力,并且基本上为您添加到pr
每个素数收集None
值。 因此,除了我们不必要地在列表中收集None
值外,它本质上与您的常规for循环类似,因此您应该允许自己使用换行符,而仅使用常规循环。
直到完成整个列表理解后,您的列表pr
才会更新。 这意味着您的列表仅包含2,因此每个可被2除的数字不在列表中(如您所见)。 每当发现新的素数时,都应更新列表。
这是因为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
比创建数组和测试数组是否为空更有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.