Python新手求问,关于lambda表达式的问题
#!/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 惰性求值问题?
Python新手求问,关于lambda表达式的问题
首先说明下,题主的代码参数有点问题哦
其次,
_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 返回
题主明白了吗?
lambda表达式就是用来创建匿名函数的,简单说就是没有名字的小函数。
比如你想写个函数把数字加10,正常写法是:
def add_ten(x):
return x + 10
用lambda可以写成一行:
add_ten = lambda x: x + 10
它最常用的地方是配合sort、map、filter这些函数。比如按字符串长度排序:
words = ["apple", "bee", "cat"]
words.sort(key=lambda w: len(w))
print(words) # ['cat', 'bee', 'apple']
或者用map给列表每个数平方:
nums = [1, 2, 3]
squared = list(map(lambda x: x**2, nums))
print(squared) # [1, 4, 9]
记住lambda只能写一行表达式,复杂的逻辑还是用def定义普通函数。
一句话建议:lambda适合写简单的一次性操作函数。
回复里不会贴代码,看起来有点乱,将就看吧,微笑脸
你看错了
用了 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
我觉得有可能是这样子的:
如果用 it = filter(lambda x: x % n > 0, it)的话,在使用 next(it)的时候,才会去找当前的 n,不管你之前过滤了多少次,等于用当前的 n 过滤了同样多次。
如果用 it = filter(_not_divisible(n), it)的话,会把每次过滤的 n 记录下来,所以就会成功输出所有素数了。
具体看上一层楼的例子。
应该只有这个解释了。
如果用 it = filter(lambda x: x % n > 0, it)的话,比如说,next(it)要输出 5 的时候,会用 3 来过滤,如果 next(it)要输出 7 的话,就用 5 来过滤 2 次(当然和过滤 1 次一样),接下来输出 9,用 7 过滤,所以这样做等于把所有奇数都输出出来了。
其实就是 1 楼说的问题
你改成 lambda n: lambda x: x % n > 0 试试
什么鬼。。
lambda 的返回值和 def 一样是个函数
it 会形成嵌套的 generator,lambda 中 n 是引用(所以会变,都是同一个),而经过函数的 n 会被拷贝一份放闭包里。
回复里可以 Gist
正解
如果要这样改的话,应该改成:(lambda n: lambda x: x % n > 0)(n)
赞同使用函数形成闭包的解析。直接使用 lambda 表达式是无法形成闭包的


