别摸我
别摸我
文章目录
  1. 一道笔试题引发的思考

一道笔试题引发的思考

一道笔试题引发的思考

有下面一段代码,问输出的是什么

1
2
3
4
def fun():
return [lambda x: x * i for i in range(4)]

print([m(2) for m in fun()])

我想都没想直接就写了[0, 2, 4, 6]

后面在突然想起来 fun() 返回的是一个 list 并不是一个 generator,所以输出肯定不是我之前想的那样。
经过研究和分析,发现了一些有意思的东西。

先来看下面一个栗子:

1
2
3
4
5
def fun_gen():
return (lambda x: x * i for i in range(4))

print([m(2) for m in fun_gen()]) # [0, 2, 4, 6]
print(type(fun_gen())) # <type 'generator'>

可以看到这里 fun_gen() 返回的是一个 generator,所以每次迭代 fun_gen() 时返回的值都会随 i 的变化而变化。

好,我们再来看另一种调用方式:

1
2
fun_gen0, fun_gen1, fun_gen2, fun_gen3 = fun_gen()
print([fun_gen0(2), fun_gen1(2), fun_gen2(2), fun_gen3(2)]) # [6, 6, 6, 6]

这里一次就把 fun_gen() 的代码执行完了,也就是说一次就把生成器迭代完了,所以返回的 i 都指向最后一个值3,所以最后打印出来的值都是6。

好了,再来看原来那段代码

1
2
3
4
5
6
7
8
9
10
11
12
def fun():
return [lambda x: x * i for i in range(4)]

print([m(2) for m in fun()]) # [6, 6, 6, 6]
print(type(fun()) # <type 'list'>

fun_list = fun()
print(len(fun_list)) # 4
print(fun_list[0]) # <type 'function'>
print(fun_list[1]) # <type 'function'>
print(fun_list[2]) # <type 'function'>
print(fun_list[3]) # <type 'function'>

这样一来就清楚很多了,fun() 返回的是一个 list,而这个list里面放了四个 function,所以 fun() 返回的时候就已经把生成器给迭代完了,而此时的 i 已经指向最后一个值3,所以后面在对 fun() 进行迭代的时候 fun() 返回 list 里的四个 function 中的i也都是3,这样一来,结果就都是6了。

支持一下
扫一扫,支持heaven
  • 微信扫一扫
  • 支付宝扫一扫