Python 为什么可以';t我将函数名替换为它';在本例中,返回值是多少?

Python 为什么可以';t我将函数名替换为它';在本例中,返回值是多少?,python,filter,generator,Python,Filter,Generator,我正在写一个python程序来打印素数。这是我的代码和一些注释 #生成一个奇数迭代器 定义奇数iter(): n=3 尽管如此: 产量 n=n+2 #返回一个lambda函数,找出哪个数不能被p整除 定义不可除(p): 返回λx:x%p>0 def primes(): 收益率2 它=_奇数_iter()#初始序列 尽管如此: n=下一个(it) yield n#将新迭代器中的第一个元素指定给它 #当我使用下面的代码时,过滤器似乎无法正常工作。 it=过滤器(λx:x%n>0,it) #当我使用下

我正在写一个python程序来打印素数。这是我的代码和一些注释

#生成一个奇数迭代器
定义奇数iter():
n=3
尽管如此:
产量
n=n+2
#返回一个lambda函数,找出哪个数不能被p整除
定义不可除(p):
返回λx:x%p>0
def primes():
收益率2
它=_奇数_iter()#初始序列
尽管如此:
n=下一个(it)
yield n#将新迭代器中的第一个元素指定给它
#当我使用下面的代码时,过滤器似乎无法正常工作。
it=过滤器(λx:x%n>0,it)
#当我使用下面的代码时,过滤器工作得很好
#it=过滤器(不可除(n),it)
#打印前10个素数
素数=素数()
对于范围(10)内的i:
打印(下一个(素数),结束=',')
我的主要问题是关于
过滤器的问题。当我在过滤器中使用函数
\u not_divisible(n)
时,我得到了输出:

2, 3, 5, 7, 11, 13, 17, 19, 23, 29
2, 3, 5, 7, 9, 11, 13, 15, 17, 19
这就是我想要的。但是,当我使用函数
\u not_divisible(n)
的返回值
lambda x:x%n>0
而不是函数本身时,我得到了以下输出:

2, 3, 5, 7, 11, 13, 17, 19, 23, 29
2, 3, 5, 7, 9, 11, 13, 15, 17, 19
过滤器似乎不起作用

我还测试
\u不可除(3)
λx:x%3>0
是否相同:

#测试如果_not_divisible(n)和lambda x:x%n>0相同,则可以正常工作。
ita=过滤器(λx:x%3>0,范围(20))
itb=过滤器(不可除(3),范围(20))
尽管如此:
尝试:
打印(下一个(ita),结束=',')
打印(下一页(itb),结束=',')
除停止迭代外:
打破
它给了我一个很好的输出:

1, 1, 2, 2, 4, 4, 5, 5, 7, 7, 8, 8, 10, 10, 11, 11, 13, 13, 14, 14, 16, 16, 17, 17, 19, 
19,

那么是什么导致了这个问题,任何人都可以帮忙吗?

这是一个狡猾的问题。问题在于上次测试中硬编码的
n

ita = filter(lambda x:x % 3 > 0, range(20))
itb = filter(_not_divisible(3), range(20))
让我们修改代码并查看

ita = []
itb = []
for n in range(3, 8, 2):
    ita.append(filter(lambda x:x % n > 0, range(20)))
    itb.append(filter(_not_divisible(n), range(20)))

for a, b in zip(ita, itb):
    print(list(a))
    print(list(b))
    print()
这是打印出来的

[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19]
[1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19]

[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19]
[1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19]

[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19]
[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19]
lambda在调用时总是查找
n
的值。在调用
ita
中的所有lambda时,它们都将看到迭代结束时的值
n
had,即7


相反,当您将该值传递给函数并从内部调用lambda时,最终会“冻结”该值。因为函数有自己的本地上下文,
n
是调用期间传递的任何值。因此,
itb
中的每个lambda每次都将从不同的上下文中查找
n

感谢您的回答!读了你的答案后,我有点困惑。在
块的第一个
之后,
ita
中的元素是三个
过滤器(λx:x%n>0,范围(20))
,但在
itb
中,有
过滤器(\u不可除(3),范围(20))
过滤器(\u不可除(5),范围(20)
和7相同。当我必须打印它们时,过滤器开始计算。此时,
n
是7,所以
ita中的
lambda
都使用7进行计算,因此将有三个相同的列表,没有7和14。这是我在你的回答中得到的,我得到了正确的理解吗?@Syvshc正确。每个函数(lambda也是函数)有自己的作用域,其中包括参数和函数中指定的任何内容。因此,当您执行
\u not \u divisible(3)
,在函数n=3的范围内。但是当您执行
lambda x:x%n
时,
n
既没有赋值,也没有作为参数传递,因此它不存在于lambda的范围内。因此,它将在封闭范围内查找它,这是执行循环的地方。当您调用lambda,此时n=7。我得到了它,我找到了一种使用lambda的新方法。如果我使用
lambda x,m=n:x%n>0
,它工作得很好。因为在每个循环中,m都会得到当前
n
值的副本,m不会随着
n
的变化而变化。谢谢!