Python 3. 里filter与generator expression的区别

# -*- coding: utf-8 -*-
"""
A test to show the difference between filter and genrator expression

As I believe, generator expression will delay the evaluation of the expression behind if

测试filter与generator expression的区别
根据下面的测试结果,我推测生成式表达式(generator expression)会对if表达式推迟赋值

"""

def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n
        
        
def _not_divisible(n):
    return lambda x: x % n > 0

    
# 下面四种写法,只有第一种是正确的,其他写法primes0,primes1,primes2,都不会正确筛掉非质数。
def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 因为为了完成_not_divisible的调用,n的值已经传进来了。
#据我理解,这个结果是        ...filter((lambda x: x % 7 >0), filter((lambda x: x % 5 >0), filter((lambda x: x % 3 >0),  _odd_iter())))

        
def primes0():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter((lambda x: x % n >0), it) # 此时n的值未传进来;传进来的是n这个变量
#据我理解,这个结果是        ...filter((lambda x: x % n >0), filter((lambda x: x % n >0), filter((lambda x: x % n >0),  _odd_iter())))

def primes1():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = (item for item in it if _not_divisible(n)(item)) # generator这种写法可能把 if 后面的运算都延迟了?
#据我理解,从最后结果反推出,这个结果是        ...(item for item in (item for item in (item for item in _odd_iter() if _not_divisible(n)(item)) if _not_divisible(n)(item)) if _not_divisible(n)(item))
#这里并没有把n的值代进去,而是保留了对n的引用,
#如果我的理解是对的,那么filter跟generator expression是不一样的,generator expression对if后面的表达式是延迟计算的。

def primes2():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = (item for item in it if (lambda x: x % n > 0)(item)) # 结果同primes1 
################ test output
print("output by primes:")       
for n in primes():
    if n < 20:
        print(n)
    else:
        break 
print("output by primes0:")       
for n in primes0():
    if n < 20:
        print(n)
    else:
        break 
print("output by primes1:")       
for n in primes1():
    if n < 20:
        print(n)
    else:
        break 
print("output by primes2:")       
for n in primes2():
    if n < 20:
        print(n)
    else:
        break 
  
   


基于廖雪峰python 3教程里的讨论:

http://www.liaoxuefeng.com/discuss/001409195742008d822b26cf3de46aea14f2b7378a1ba91000/001480687071611fab98c8f381a4b63a1a94132134c432d000?page=1


14:49:47 2016-12-03

posted on 2016-12-03 14:52  603学徒  阅读(649)  评论(0编辑  收藏  举报