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) for n in primes(): if n < 1000: print(n) else: break
最开始的时候是准备把代码的内容清楚理解:
首先第一块是一个generator(因为有yield关键字),内容是生成奇数,只有当出现next()命令或者for循环才会一步步执行。
第二块是去掉已经确认是素数(n)的倍数,x是输入。
举几个例子(侵删关于廖雪峰老师filter教程中求素数详细理解-布布扣移动版-m.bubuko.com
1. c=lambda x:x*x print(c(2)) 输出为4 2. c=lambda x:x%2>0
print(c(3))
输出为True 3.
c=lambda x:x%2>0 print(c(2)) 输出为False
从上面的例子中可以看出x是输入
第三块自己理解为是控制第一第二块的,起引导作用的函数
然后for循环输出1000以内的素数
当我大概了解了各块功能之后,发现根本无法理解其中的某些命令。所以最后选择进行一步一步的调试+查看各类文章,先从理解它的运行规律开始。
1.进入primes()函数,yield 2,得到n=2,输出
2.it=_odd_iter(),这步的理解是通过下面的链接来理解的。python中yield的用法详解——最简单,最清晰的解释_mieleizhi0522的博客-CSDN博客_yield
it=_odd_iter()这一步即得到一个生成器,不会输出内容,it里面为空,每一次next(it)都会覆盖之前的值,存在电脑同样的地方。
3.n=next(it)开始调用_odd_iter()函数,得到n=3,同时这里也可以理解为it存储了3。yield n,将3输入for循环,然后打印出来
4.接着yield n 后的内容,it=filter(_not_divisible(n),it)#现在还不理解的地方,有两种理解:第一种,filter函数可以看作(x for x in it if _not_divisible(n)),那么x(输入)就是3,那就像图示所表现的,n是没有定义过的。
第二种就是it=n,filter(_not_divisible(n),it)中it带入的是n,这个感觉是违背常理的,但是从后续的步骤来看,确实是第二种。属实非常不能理解了。(之后的理解都是在默认第二种可能是正确的前提下的)
额外一点知识:当调用filter函数时,想要输出结果时,会发现得到的是<filter object at >,只有在filter函数外面添加list()时才会显示。上网一查调用filter返回<filter object at。。。> - 问答 - Python中文网python生成器函数_自定义生成器函数模拟Python内置函数filter()_weixin_39837105的博客-CSDN博客
得知filter函数返回的是一个filter对象,可以通过list()或者for循环取出内容(可以类比为生成器?),这里可以类比it=_odd_iter()即不会输出内容,只是形成一个生成器。
5.进入_not_divisible(n)确定n=3(这里也不太理解为什么会进入这个函数,并没有触发它啊。为什么n=3呢
6.继续n=next(it),这里的it=filter(_not_divisible(n),it),首先括号里面的it是一个生成器,所以先会对其进行next(it),即进入_odd_iter()函数,得到n=5,并输出5。
7.进入_not_divisible(n)函数输入为刚刚输出的5,5%3>0,所以结果为true,yield n (n=5)输出
8.再次回到it=filter(_not_divisible(n),it),然后进入_not_divisible(n)函数,确定n=5。
9.n=next(it)进入第一个函数得到n=7,再把7作为x输入第二个函数,又出现了一个疑问,就是n此时=3,(被迫这样理解:迭代,8中括号里的it是4中被赋值的it,而4中括号里的it为3,所以n先等于3,然后5)return为true,继续n=5,retrun为true,回到primes()函数输出7,for循环,打印7
10.再次回到it=filter(_not_divisible(n),it),去第二个函数那里确定n=7,继续next(it)进入第一个函数,得到n=9,作为x输入第二个函数,此时n=3,9%3==0,return为false,回到第一个函数,得到n=11,作为x输入第二个函数,又开始从3开始判断,return全为true,进入第三个函数输出11,for循环,打印11
到这里整个代码的运行过程已经了然,但是对于其内核还是懵懵懂懂,存档,之后再回来看看。