Python常见面试题014.请说出下面的代码返回结果是什么?

1|0示例代码

def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda: num ** c) return nums[d]() print(fun(1, 5, 2, 0)) print(fun(1, 5, 2, 1)) print(fun(1, 5, 3, 1)) print(fun(1, 10, 2, 1))
  • 答案是
16 16 64 81

2|0原因分析

  • 调用函数fun(1, 5, 2, 0)

  • 意味着

    nums = [] for num in range(1, 5): nums.append(lambda: num ** 2) return nums[0]()
  • 所在列表nums中是多个匿名函数

  • 应该依次是

    lambda :1**2 lambda :2**2 lambda :3**2 #依次类推 ...
  • 那按照我们的想法,nums[0]应该是lambda :1**2,调用应该得到1才是

    >>> demo1 = lambda :1**2 >>> demo1() 1 >>> demo2 = lambda :2**2 >>> demo2() 4
  • 但结果并不是这样的,nums[0]()得到的结果是range()结束值=5-1时的4**2

  • 甚至从答案可以看出来nums[1]()也是

  • 依次类推,fun(1, 5, 3, 1)=>nums[1]()=>结束值5-1=4的三次方=>64


  • 所以规律是有了,道理何在?

  • 看下代码

    def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda: num ** c) return nums[d]()
  • 这是因为 num 不是 lambda 函数的内部变量,而是定义于外部作用域中的,并且 num 是在调用 lambda 时访问的——而不是在定义时访问。循环结束时 num 的值是 4 ,所以此时所有的函数都将返回 4**2 ,即 16

3|0拓展

  • 那要如何才能符合我们的预期呢?nums[0]()nums[1]()是不一样的

  • 你可以将值保存在 lambda 局部变量,以使其不依赖于全局 num 的值

    def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda n=num: n ** c) # n = num return nums[d]() print(fun(1, 5, 2, 0)) print(fun(1, 5, 2, 1)) print(fun(1, 5, 3, 1)) print(fun(1, 10, 2, 1)) # 依次输出 1 4 8 4
  • 以上 n=num 创建了一个新的 lambda 本地变量 n,并在定义 lambda 时计算其值,使其与循环当前时点的 num 值相同。这意味着 n 的值在第 1 个 lambda 中为 0 ,在第 2 个 lambda 中为 1 ,在第 3 个中为 2,依此类推

以上参考

https://docs.python.org/zh-cn/3.9/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result


__EOF__

本文作者博客已废弃
本文链接https://www.cnblogs.com/wuxianfeng023/p/17272405.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   博客已废弃  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示