#!/usr/bin/env python3 # -*- coding: utf-8 -*- def main(): for n in primes(): if n < 100: print(n) else: break 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) if __name__ == '__main__': main()
如果将
it = filter(_not_divisible(n), it)
改成
it = filter(lambda x: x % n > 0, it)
两次结果不一样,是 n 的作用域问题? filter 惰性求值问题?
![]() | 1 rwdy2008 2017-09-22 15:33:41 +08:00 首先说明下,题主的代码参数有点问题哦 其次, _not_divisible 函数你这样写返回时的一个 function,function 永远是 True 直接写 lambda 返回的是 True 或者 False filter 内置函数对 True 结果处理,这应该就是问题所在 最后, 看下面代码,题主参考下应该就明白了 def _not_divisible(n): return lambda x: x % 3 > 0 filter(_not_divisible, [5,6]) [5, 6] _not_divisible(5) <function <lambda> at 0x036DAA30> _not_divisible(6) <function <lambda> at 0x036F82F0> 上面这两个都返回的是 function filter(lambda x: x % 3 > 0, [5,6]) [5] f = lambda x: x % 3 > 0 filter(f, [5,6]) [5] f(5) True f(6) False 这个有 False 返回 题主明白了吗? |
![]() | 2 rwdy2008 2017-09-22 15:34:36 +08:00 回复里不会贴代码,看起来有点乱,将就看吧,微笑脸 |
![]() | nbsp; 3 ballshapesdsd 2017-09-22 16:47:45 +08:00 @rwdy2008 你看错了 用了 python 好多年了,我也搞不懂,坐等高手,我感觉是不是跟下面这个有关: 1: for i in range(5): f=lambda x:x+i i=5 print f(1) output: 6 6 6 6 6 2: def aaa(n): return lambda x:x+n for i in range(5): f=aaa(i) i=5 print f(1) output: 1 2 3 4 5 |
![]() | 4 ballshapesdsd 2017-09-22 17:06:29 +08:00 我觉得有可能是这样子的: 如果用 it = filter(lambda x: x % n > 0, it)的话,在使用 next(it)的时候,才会去找当前的 n,不管你之前过滤了多少次,等于用当前的 n 过滤了同样多次。 如果用 it = filter(_not_divisible(n), it)的话,会把每次过滤的 n 记录下来,所以就会成功输出所有素数了。 具体看上一层楼的例子。 应该只有这个解释了。 |
![]() | 5 ballshapesdsd 2017-09-22 17:08:56 +08:00 如果用 it = filter(lambda x: x % n > 0, it)的话,比如说,next(it)要输出 5 的时候,会用 3 来过滤,如果 next(it)要输出 7 的话,就用 5 来过滤 2 次(当然和过滤 1 次一样),接下来输出 9,用 7 过滤,所以这样做等于把所有奇数都输出出来了。 |
![]() | 6 wang9571 2017-09-22 17:17:57 +08:00 其实就是 1 楼说的问题 你改成 lambda n: lambda x: x % n > 0 试试 |
![]() | 7 ballshapesdsd 2017-09-22 17:32:34 +08:00 @wang9571 什么鬼。。 |
8 kkzxak47 2017-09-22 17:32:45 +08:00 via Android lambda 的返回值和 def 一样是个函数 |
![]() | 9 khowarizmi 2017-09-22 20:23:18 +08:00 via iPhone it 会形成嵌套的 generator,lambda 中 n 是引用(所以会变,都是同一个),而经过函数的 n 会被拷贝一份放闭包里。 |
![]() | 10 Technetiumer 2017-09-22 20:55:34 +08:00 via Android @rwdy2008 回复里可以 Gist |
11 ManjusakaL 2017-09-22 22:20:06 +08:00 @khowarizmi 正解 |
12 Jeepeng OP @rwdy2008 filter 第一个参数是函数,_not_divisible(n) 是函数, lambda x: x % n > 0 也是函数,这个参数没问题 |
![]() | 14 LeonHuayra 2017-09-22 23:25:52 +08:00 @khowarizmi 赞同使用函数形成闭包的解析。直接使用 lambda 表达式是无法形成闭包的 |