首先,列出从
2
开始的所有自然数,构造一个序列:2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取序列的第一个数
2
,它一定是素数,然后用2
把序列的2
的倍数筛掉:3,
4, 5,6, 7,8, 9,10, 11,12, 13,14, 15,16, 17,18, 19,20, ...取新序列的第一个数
3
,它一定是素数,然后用3
把序列的3
的倍数筛掉:5,
6, 7,8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...取新序列的第一个数
5
,然后用5
把序列的5
的倍数筛掉:7,
8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...不断筛下去,就可以得到所有的素数。
用Python来实现这个算法,可以先构造一个从
3
开始的奇数序列:
题解:
- 定义奇数生成器,思考:因为素数除了2以外的偶数均不是素数
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
- 设置筛选函数
def _not_divisible(n):
return lambda x: x % n > 0
- 定义一个生成器,不断返回下一个素数
def primes():
yield 2
it = _odd_iter() # 初始序列,已经生成一整个序列了,但是并不
while True:
n = next(it) # 返回序列的第一个数
yield n
it = filter(_not_divisible(n), it) # 构造新序列
-
这个生成器先返回第一个素数
2
,然后,利用filter()
不断产生筛选后的新的序列。由于
primes()
也是一个无限序列,所以调用时需要设置一个退出循环的条件:
# 打印1000以内的素数:
for n in primes():
if n < 1000:
print(n)
else:
break
理解匿名lambda函数
def test_lambda():
return lambda x, y: x + y
test = test_lambda()
print(test(3, 2)) # 5
上面函数中,test_lambda
函数并没有位置参数,但是将其赋给变量test
后便可以调用
如果,直接使用test_lambda(3, 2)
将返回错误
def _not_divisible(n):
return lambda x: x % n > 0
对于上面函数的理解,其实道理和test_lambda
相同
f = _not_divisible(3)
print(f(5)) # True
利用变量引用函数,然后再是匿名函数的参数x=5
的传入
大概意思就是如此,表达上还有欠缺,有大佬可以指正
扩展:回文整数
回数是指从左向右读和从右向左读都是一样的数,例如12321
,909
。请利用filter()
筛选出回数:回数是指从左向右读和从右向左读都是一样的数,例如12321
,909
。请利用filter()
筛选出回数:
def is_palindrome(n):
k = n
x = 0
while(n != 0):
x = x * 10 + (n % 10)
n = n // 10
if x == k:
return True
return False
# 测试:
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
print('测试成功!')
else:
print('测试失败!')
参考: