python lambda结合列表推导式---问题和解决方案;函数定义默认形参赋值为可变参数时需要注意的点

def testFun():
    temp=[lambda x:i*x for i in range(4)]
    for i in temp:
        print(id(i))
    return temp
for everyLambda in testFun():
    print(everyLambda(2))
运行结果:
2208214063440
2208214063576
2208214063712
2208214063848
6
6
6
6
**



类似问题:

func2 = [lambda x: x*i for i in range(10)]
a=[f2(2) for f2 in func2]
print(a)
# 函数对象只有在调用的时候才开始对内部的变量进行引用, 对i来说, 当函数对它引用的时候, 它已经变为9, 所以10个函数
# 都引用了i=9.
运行结果:[18, 18, 18, 18, 18, 18, 18, 18, 18, 18]

解决方案一:

func3 = [lambda x, i=i: x*i for i in range(10)]
b=[f3(2) for f3 in func3]
print(b)
#给函数设定默认参数, 在生成函数对象的时候把i赋值给它,给函数默认值时, 这个默认值就变为了local, 根据LEGB原则,
# 在local中存在的变量, 我们就不需要到enclosing中寻找
运行结果:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]


解决方案二:

func4 = (lambda x: x*i for i in range(10))
c=[f4(2) for f4 in func4]
print(c)运行结果:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
#对于生成器, 只有你需要的时候它才会求值, 这也是和列表解析式的区别, 列表解析式只要你运行, 马上就把i变为了9,
# 可是生成器不会, 当你调用第一个函数的时候, 他把相应的i求出来, 然后停止, 等你下一次调用
文章参考:https://www.zhihu.com/question/56193983Python  LEGB规则:
L-Local(function);函数内的名字空间
E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)
G-Global(module);函数定义所在模块(文件)的名字空间
B-Builtin(Python);Python内置模块的名字空间 LEGB规定了查找一个名称的顺序为:local-->enclosing function locals-->global-->builtin文章参考:https://www.jianshu.com/p/3b72ba5a209c

附加一个小知识点:

def fun(li=[]):
    li.append("abc")
    return li
print(fun())
print(fun()) 结果:['abc']['abc', 'abc'] 定义函数, 默认参数的默认值如果是可变参数则内存地址会保持不变的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值