有人可以通过这个筛子逐行走我的路吗?我试图开发自己的筛子,但大多数更快的筛子都包含我不理解的语法(就像我已经评论过的那样)。很抱歉,如果这是一个新手问题 - 如果你有任何链接可以帮我筛选,他们将非常感激。
def rwh_primes1(n):
""" Returns a list of primes < n """
sieve = [True] * (n/2) # What does the '[True]' mean?
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i/2]: # The same complaint as in line 3, I don't understand the variable 'sieve'
sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) # how is sieve used here - it seems to be as a list but i'm unsure
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]] # 'sieve' is confusing me here yet again.
答案 0 :(得分:4)
我将每行代码的含义用斜体字表示,并在正常面部文本中添加我的注释。
sieve = [True] * (n/2)
声明一个新的局部变量sieve
并将其初始化为值[True] * (n/2)
。该表达式是什么意思? [True]
是仅包含布尔值True
的单元素列表。将列表乘以数字会重复列表,因此sieve
现在是n/2
- 所有 - True
值的元素列表。
for i in xrange(3, int(n**0.5)+1, 2):
以2为步长开始计数,从3开始,到sqrt(n)结束。这个特殊的范围选择是Sieve算法的优化:我们可以从1到1一直计算n以1为单位,但效率较低。
if sieve[i/2]:
查看i/2
列表的sieve
元素。如果它是True
,则继续向下if
分支。作者正在使用i/2
来补偿代码按2步计数的事实这样你可以使用更短的列表并使用更少的内存。
sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
将sieve
的每个第i个元素更新为False
,从i * i / 2开始。 sieve[i*i/2::i]
称为slice notation - 因为它出现在作业的左侧,所以此代码将更新那片sieve
。右侧是list-times-number技巧的重复。它计算一个正确长度的全部False
列表。
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]
此代码只是将True
中的False
/ sieve
值转换为素数列表。该计算通过将每个sieve
值的索引乘以2来补偿True
不包含任何偶数的事实。
答案 1 :(得分:1)
假设n = 7:
sieve = [True] * (n/2) # What does the '[True]' mean?
列出长度为n的一半的布尔值。例如,sieve = [True,True,True](因为3.5是在python2中向下舍入的分数长度)
所以xrange(3,int(n**0.5)+1,2)
将是一个生成器,为我们提供这个序列:[]
for i in
if sieve[i/2]: # The same complaint as in line 3, I don't understand the variable 'sieve'
sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) # how is sieve used here - it seems to be as a list but i'm unsure
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]] # 'sieve' is confusing me here yet again.
当我们看到[i :: 2]或某些只是大海时,我们会以重复的间隔对列表进行切片。所以如果mylist包含(0..19):
>>> mylist = range(20)
>>> mylist[0::1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> mylist[0::2]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> mylist[0::3]
[0, 3, 6, 9, 12, 15, 18]
尝试自己玩这个,以便熟悉它。
因此,在这种情况下,sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
会将列表中的每个第i个值设置为False。