Python 内建的
函数用于过滤序列。
- filter()
和
类似,
- map()
也接收一个函数和一个序列。和
- filter()
不同的是,
- map()
把传入的函数依次作用于每个元素,然后根据返回值是
- filter()
还是
- True
决定保留还是丢弃该元素。
- False
例如,在一个 list 中,删掉偶数,只保留奇数,可以这么写:
- defis_odd(n):return n %2 ==1
- list(filter(is_odd, [1,2,4,5,6,9,10,15]))# 结果: [1, 5, 9, 15]
把一个序列中的空字符串删掉,可以这么写:
- defnot_empty(s):return sand s.strip()
- list(filter(not_empty, ['A','','B',None,'C',' ']))# 结果: ['A', 'B', 'C']
可见用
这个高阶函数,关键在于正确实现一个 "筛选" 函数。
- filter()
注意到
函数返回的是一个
- filter()
,也就是一个惰性序列,所以要强迫
- Iterator
完成计算结果,需要用
- filter()
函数获得所有结果并返回 list。
- list()
计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:
首先,列出从
开始的所有自然数,构造一个序列:
- 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
- def_odd_iter():
- n =1whileTrue:
- n = n +2yield n
注意这是一个生成器,并且是一个无限序列。
然后定义一个筛选函数:
- def_not_divisible(n):returnlambda x: x % n >0
最后,定义一个生成器,不断返回下一个素数:
- defprimes():yield2
- it = _odd_iter()# 初始序列whileTrue:
- n = next(it)# 返回序列的第一个数yield n
- it = filter(_not_divisible(n), it)# 构造新序列
这个生成器先返回第一个素数
,然后,利用
- 2
不断产生筛选后的新的序列。
- filter()
由于
也是一个无限序列,所以调用时需要设置一个退出循环的条件:
- primes()
- # 打印1000以内的素数:for nin primes():if n <1000:
- print(n)else:break
注意到
是惰性计算的序列,所以我们可以用 Python 表示 "全体自然数","全体素数" 这样的序列,而代码非常简洁。
- Iterator
来源: http://www.bubuko.com/infodetail-2068611.html