记录一道有趣的python笔试题:匿名函数与闭包的综合运用

前言

最近做某公司的数据挖掘岗的笔试题,遇到一道python题,让我印象深刻。如下

def num():
    return [lambda x:x*i for i in range(4)]

print([m(?) for m in num()])

如果打印的结果为[6,6,6,6],问❓处的数字应该为多少?

分析

首先,很显然的,num()函数返回的是4个匿名函数组成的列表,那么遍历这4个函数并调用的结果就是我们的打印结果。如果不仔细想清楚,会很自然的认为答案就是[0*❓,1*❓,2*❓,3*❓]。但是如果是这样,那么无论❓处输入什么数字,结果都不是[6,6,6,6]。这也是我当时第一眼的想法。但是,如果我们我们再仔细想一想,就会发现num()函数内部构成闭包,我们可以将其改写为如下更易懂的形式。

def num():
	func_li=[]
	for i in range(4):
		def func(x):
			return x*i
		func_li.append(func)
	return func_li

# 真正的执行
for func in num():
	print(func())

在我们调用num()中的每个func()时,func()才开始去寻找需要的参数i,因为函数内部根本找不到i这个变量,但是这个时候,内部的for循环结束,此时存在变量i=3,因此对于调用每个func()来说,返回的结果都是x*3。当明白这个点之后,这个问题也就迎刃而解了,❓处的数字自然就是2。

如果我们希望当❓处数字为2时,输出的结果是[0,2,4,6],那么可以将num()修改为如下

def num():
    return [lambda x,i=i:x*i for i in range(4)]

即让每个函数都存储当前for循环的i值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值