目的:更熟悉应用generator。

参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017404530360000

素数定义:

素数:质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数。

方法:

计算素数的一个方法是埃氏筛法

首先,列出从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把序列的3的倍数筛掉:

5, 6, 7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...

第四步,取新序列的第一个数5,然后用5把序列的5的倍数筛掉:

7, 8910, 11, 12, 13, 141516, 17, 18, 19, 20, ...

后续,不断筛下去,就可以得到所有的素数。

代码:

2是素数,直接从一个奇数序列开始筛选:

# 生成一个奇数序列。从3开始
def _odd_iter():
n = 1
while True:
n += 2
yield n

筛选函数:

  1. 由上面的分析可知,每次筛选,都除以序列的第一数。
  2. 条件是x % n > 0。x为序列中被判断的数字,n为该序列的第一个数字。整除结果==0的都不是素树。要从序列中删除。
  3. 所以,判断表达式是不固定的。定义一个函数,传入参数n, 返回一个lambda表达式用于判断。
# 传入参数n,生成不同的lambda表达式。
def _not_divisible(n):
# 返回一个lambda表达式。用于判断x,是不是素数。
# 素数,只能被1和自身整除的自然数叫做素数。
# 整除就是余数为0。
# 如果被非自身数字整除,即余数为0,那自然不是素数,删除掉。
return lambda x: x % n > 0

主函数:

  1. 第一行代码:yield 2,返回素数2。
  2. 第二行代码:创建生成器,第一次运行,它产生奇数序列,这个序列会逐步被筛选,去掉非素数字。
  3. 循环代码:
    1. n = next(it), 得到序列的第一个数字。
    2. yield n,  它是素数。
    3. 用filter()来筛选, it生成器中的数字。 因为it是可迭代的。并把新的序列赋值给it变量。

⚠️重新理解3。filter函数对生成器对象it进行筛选,其实就是代码组合,把_not_divisible(n)返回的lambda表达式和it自身的代码组合,形成新的对象<filter object>。

⚠️我的理解是,原先的_odd_iter()产生的算法不再用,而是使用增加了lambda条件判断的新的算法,<filter object>。

⚠️这一步并不是真的筛选掉不符合的数字,_ood_iter()只是代表了生成序列数字的算法。只不过这个算法被新的算法替代了。

def primes():
yield 2 #2是素数。
it = _odd_iter() #创建一个<generator object _odd_iter>,代表奇数序列。
while True:
n = next(it) #返回奇数序列的一个数。
yield n #这个数是素数。所以返回。
# 创建一个<filter object>, 代表新序列。
it = filter(_not_divisible(n), it)

由于primes()所代表的算法生成的是一个无限序列,没有退出机制,所以调用时需要设置一个退出循环的条件:

for n in primes():
if n < 1000:
print(n)
else:
break

⚠️primes本身是生成器函数, primes()就是一个生成器,它自身不储存数据,只储存生成数据的算法。

总结;

由本例可知,generator其实就是算法,它不会一次性产生全部数据,而是根据调用的次数,逐步向内存写入数据。

本例把一个生成器对象作为参数传入了filter()函数,其实就是对这个生成器的代码进行更新,即改进算法。最后返回一个新的迭代器。本例返回的是<filter object>。

Python:用filter函数求素数 (再理解generator)的更多相关文章

  1. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  2. python中filter函数

    python中filter()函数   filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断 ...

  3. python的filter()函数

    filter()函数是 Python 内置的另一个有用的高阶函数. filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,fil ...

  4. python中filter()函数

    filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filt ...

  5. 2.python函数编程-filter函数

    fileter功能主要使用在需要对数据进行多种操作,并对数据进行过滤的操作. 普通函数实现: movie = ['sb_alex', 'wupei', 'tiger', 'goosb','xxfd', ...

  6. Python之filter函数

    描述 filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表. 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 Tru ...

  7. python的filter函数的使用方法详解以及使用案例,是否以什么结尾,是否大于什么(判断是True,则留下来)

    1.总共有3个人看电影,有2个人看电影经常说话,我们把他们两个过滤出去 move_people=["gouguoqi","beiye_sb","xiu ...

  8. Python之filter()函数与替代实现

    介绍 filter(f,x)函数用于过滤序列并返回迭代器,结果保留x中f为True的元素,需要新的序列通过list()转换. 例子 过滤列表中的字符串,保留数字. >>> i = [ ...

  9. Python 中filter函数用法

    filter()和map一样,接收一个函数和一个序列.和map不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素 过滤出奇数: de ...

随机推荐

  1. Hbase标准配置文件 + 增删改查

    1.可用配置文件 <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href=&q ...

  2. flask的session基础认识

    from flask import Flask,session from datetime import timedelta import os app = Flask(__name__) app.c ...

  3. golang break label 与goto label

    本文链接:https://blog.csdn.net/itbsl/article/details/73380537 与其他语言一样,Go语言也支持label(标签)语法:分别是break label和 ...

  4. 2019牛客暑期多校训练营(第九场)-D Knapsack Cryptosystem (折半搜索)

    题目链接:https://ac.nowcoder.com/acm/contest/889/D 题意:题意简单,从大小为36的集合中选若干元素使得他们的和为sum. 思路:第一感觉用搜索,复杂度为2^3 ...

  5. [转帖]如何在Linux上使用命令行查看硬件信息

    如何在Linux上使用命令行查看硬件信息 时间:2016-01-13   作者:admin 分类:新手入门 阅读:126次 http://embeddedlinux.org.cn/emb-linux/ ...

  6. [转帖] ./demoCA/newcerts: No such file or directory openssl 生成证书时问题的解决.

    接上面一篇blog 发现openssl 生成server.crt 时有问题. 找了一个网站处理了一下: http://blog.sina.com.cn/s/blog_49f8dc400100tznt. ...

  7. Oracle-DQL 6- 子查询

    子查询: --查询emp表中工资高于allen的员工信息SELECT sal FROM empWHERE ename = 'ALLEN'; SELECT * FROM empWHERE sal > ...

  8. Linux试题亿点点

    1. 在登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么(b) A.NID B.PID C.UID C.CID # process ID 进程id号 # UID 用户iD号 ...

  9. T100——报表的小计数量、小计金额,总计金额

    范例:cxmr540_g01 范例代码: ON EVERY ROW #add-point:rep.everyrow.before name="rep.everyrow.before" ...

  10. 怎样禁止 html 中 <textarea> 标签可以拉伸改变大小 ?

    1. 一般来说, 使用 <textarea> 这个标签都会禁用掉它的这个默认属性, 不然可能会被用户玩儿坏, 而且也不利于其他元素的展示, 使用到的属性是 resize , 改为 none ...