python中for循环中使用lambda表达式遇到的坑

python中for循环中使用lambda表达式遇到的坑

在接手这个项目后,由于主要使用的语言都是python,故本着已有语言基础以用到就现学现用的想法使用python。于是就过了一遍基础语法,然后就开始了现学现用的过程,一开始关于cv的一些基本操作什么的还是能够解决的。直到最近被一个小bug困扰了很长时间,整个国庆都没有找出来(虽然有四天在画uml图,但是也是实在看那段代码看吐了,不想改了),才发现不了解语言特性还是会掉到坑里面。

  • problem
    我将我遇到的问题简化了:
step=3
j=[1,2,3]
f=[]
for i in range(step):
    fx=lambda x:x*j[i]
    f.append(fx)
print(f[0](2))

上面这段代码,按照我以其他语言的思维来看打印结果应该是2,但是打印结果却是6。原因是f中所有的函数都是为最后一次,引用的是同一个对象。那么怎样解决这个问题呢?
解决方法有很多种:
1.

step=3
j=[1,2,3]
f=[]
for i in range(step):
    fx=lambda x,i=i:x*j[i]
    f.append(fx)
print(f[0](2))

在lambda函数中添加默认参数循环索引
2.

step=3
j=[1,2,3]
f=[]
for i in range(step):
    fx=lambda i:lambda x=i:x*j[i]
    f.append(fx(i))
print(f[0](2))

用又一层的lambda进行封装,同样将循环索引当作参数传入。同理用def 定义函数进行封装也可以,但是适用场景有限了(不能在函数内的循环使用)。

  • summary
    这两种方法其实原理都一样,就是将lambda表达式中的索引变量固定下来。第二种方法甚至有些累赘,第一种方法比较简洁干脆。之所以出现这样的问题,是因为lambda表达式在执行的时候才会去寻找变量i,而这时所有的i变量已经都为3了(python 中for循环索引作用域并不止在循环内部)。这种问题感觉光盯着代码,乍一看还真就觉得自己没错。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值