1、问题

有这么一个小面试题:

看下面代码请回答输出的结果是什么?为什么?

result = [lambda x: x + i for i in range(10)]
print(result[0](10))

2、解答

当你看到这篇文章的时候如果不知道这个知识点肯定会拿去直接运行,输出的结果是什么呢?

结果是:19

通过result[0~9](10)结果都是19就,懵逼了吧~~

想知道这个我们先看几个知识点

2.1、列表生成式

顾名思义,列表生成式就是一个用来生成列表的特定语法形式的表达式。

语法格式:

[expression for iterable_var in iterable]

工作过程:

  • 迭代iterable的每个元素
  • 把迭代的值赋值给iterable_var,然后通过expression的表达式进行计算得到一个新的值
  • 最后把所有expression的值以新列表的形式返回

工作过程类似于:

L = []

for i in range(10):
# 举例expression 表达式 iterable_var * 5 ,最后把这个结果加到列表中
L.append(i * 5)

点到为止,我们来看下我们的这个小面试题

result = [lambda x: x + i for i in range(10)]
# 后面的lambada x:x +i 为expression 这是一个普通的lambada表达式那他生成的结果是什么? 一个一个的函数
# 看下面的例子就舒服多了
L = [] for i in range(10):
L.append(lambda x: x + i)

那在我们执行result[0](10),其实就是在执行lambda 10: 10 + i ,但是为什么每个i都是9呢?

2.2、函数内部变量的后期绑定(last binding)

我们在写一个函数的时候,函数内不保存这个变量的值,而是在执行的时候去找这个值在哪里绑定上的。

举个例子来说我们在函数中定引用了一个变量,可以不需要提前定义我们只要在使用前定义就可以了,如下面代码

def func():
print(foo) foo = "hello tim" func()

注:这里有个点稍微提醒下,调用函数时这个函数必须是提前定义好的,这个我们称之为“前向引用”,而函数内部变量可以后期再定义,我们称之为“后期绑定”

因为这个变量不是在lambda内定义的,而是在列表生成式内定义的,我先把列表生成式翻译一下:

def make_list():
L =[]
for i in range(10):
def inner(arg):
return i + arg
L.append(inner)
return L result = make_list()
print(result[2](10))

看上面的代码最后返回的都是一个一个的函数,而这个i的值是在循环的时候赋值的,那我们知道这个i的值不是在,inner(lambda)函数中定义的,而是引用的上层函数的变量,当我们使用inner去调用的时候,这时这个for循环已经结束了,i的值也就变成固定了9

所以每当我们通过函数lambda x: x + i 的时候这个i永远是9

2.3、小作修改

那如果说我不想要这样的结果,我想要i是循环的值怎么办,不要直接引用上层变量,把变量传进来就可以了

result = [lambda x, i=i, : x + i for i in range(10)]
print(result[1](10))

翻译一下

def make_list():
L =[]
for i in range(10):
def inner(arg, i=i):
return i + arg
L.append(inner)
return L result = make_list()
print(result[2](10))

2.4、闭包

简单解释下这个概念,在嵌套函数内,嵌套函数应用上层函数的变量(不是全局变量)称之为闭包,

def func():
x = 1 def inner():
print(x)

当我们执行func的时候就会生成一个闭包,func执行完后里面的变量x不会被回收,因为嵌套函数inner还在使用它,常见的应用场景就是我们的装饰器

Python【知识点】面试小点列表生成式小坑的更多相关文章

  1. python协程函数应用 列表生成式 生成器表达式

    协程函数应用 列表生成式 生成器表达式   一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._n ...

  2. Python高级特性:Python迭代、生成器、列表生成式

    迭代 给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration). 在java和C语言中,迭代是通过循环list的下标来完成的,Pyth ...

  3. Python学习笔记6(列表生成式)

    1.生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >>> range(1, 11) [1, 2, 3 ...

  4. Python 入门(十)列表生成式

    生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >>> range(1, 11) [1, 2, 3, ...

  5. 【Python】学习笔记之列表生成式

    列表生成式 主要用于生成较为复杂的列表 常用用法 >>> [x * x for x in range(5) if x % 3 !=1 ] [0, 4, 9] #返回除以3余数不为1的 ...

  6. 【Python】python内置函数、列表生成式、生成器

    一.内置函数 1 print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真 2 print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真 3 pri ...

  7. python学习之模块(pip),列表生成式,模块操作mysql,excel

    python基础 生成式 列表生成式 格式 [表达式 for 表达式 in 迭代对象 (可加判断)] 原: res1 = [] for i in range(1,5): res1.append(i) ...

  8. python学习那点事---列表生成式实现大小写字母相互转换

    题目: 已知列表list=["pYTHON","iS",eASY],要求使用列表生成式实现,生成一个新的列表,要求将大写字母转换为小写字母,小写字母转换为大写字 ...

  9. Python 函数递归-三元表达式-列表生成式-字典生成式-匿名函数-内置函数

    上节课复习: 1. 无参装饰器 def 装饰器名字(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res ...

随机推荐

  1. day59

    轮播图作业 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...

  2. 判断库位是否参与MRP运算

    表 T001L 字段DISKZ (库存地点MRP标识)为空,参与MRP运算,为1不参与.

  3. 20155317王新玮《网络对抗技术》实验9 web安全基础实践

    20155317王新玮<网络对抗技术>实验9 web安全基础实践 一.实验准备 1.0 实验目标和内容 Web前端HTML.能正常安装.启停Apache.理解HTML,理解表单,理解GET ...

  4. LCA的一些算法

    LCA,就是求树上任意两点的最近公共祖先 (本题图片与代码均为Luogu3379) 方法我好像讲过一个,这次把主要的三个一起讲一讲 <1> 倍增(O(n log n)) 我们先考虑最基本的 ...

  5. python 回溯法 子集树模板 系列 —— 14、最长公共子序列(LCS)

    问题 输入 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) 输出 输出最长的子序列,如果有多个,随意输出1个. 输入示例 belong cnblogs 输出示例 blog ...

  6. C#_正则表达式

    概述 正则表达式,主要是用符号描述了一类特定的文本(模式).而正则表达式引擎则负责在给定的字符串中,查找到这一特定的文本. 本文主要是列出常用的正则表达式符号,加以归类说明.本文仅仅是快速理解了正则表 ...

  7. 批量备份H3C交换机路由器配置

    第一种(使用ftp下载配置文件): #!/bin/bash datetime=`date +%Y%m%d` BAKTIME=`date +%Y%m%d%H%M%S` user="admin& ...

  8. iOS开发面试题整理

    前言 本文借鉴整理了iOS高级开发常见的面试题,并且分博客一一分析,希望能和大家一起进步学习. 欢迎大家关注我的 Github

  9. 【容器魔方解读】AWS Re:Invent 2018大会

    每年云计算领域技术与商业风向标之一的AWS Re:Invent大会上周在美国拉斯维加斯召开,如往届一样,AWS密集发布了上百项的新产品或新技术.随着国内近两年云计算尤其是公有云的普及度越来越高,国内各 ...

  10. CEPH LIO iSCSI Gateway

    参考文档: Ceph Block Device:http://docs.ceph.com/docs/master/rbd/ CEPH ISCSI GATEWAY:http://docs.ceph.co ...