Python【知识点】面试小点列表生成式小坑
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【知识点】面试小点列表生成式小坑的更多相关文章
- python协程函数应用 列表生成式 生成器表达式
协程函数应用 列表生成式 生成器表达式 一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._n ...
- Python高级特性:Python迭代、生成器、列表生成式
迭代 给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration). 在java和C语言中,迭代是通过循环list的下标来完成的,Pyth ...
- Python学习笔记6(列表生成式)
1.生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >>> range(1, 11) [1, 2, 3 ...
- Python 入门(十)列表生成式
生成列表 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11): >>> range(1, 11) [1, 2, 3, ...
- 【Python】学习笔记之列表生成式
列表生成式 主要用于生成较为复杂的列表 常用用法 >>> [x * x for x in range(5) if x % 3 !=1 ] [0, 4, 9] #返回除以3余数不为1的 ...
- 【Python】python内置函数、列表生成式、生成器
一.内置函数 1 print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真 2 print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真 3 pri ...
- python学习之模块(pip),列表生成式,模块操作mysql,excel
python基础 生成式 列表生成式 格式 [表达式 for 表达式 in 迭代对象 (可加判断)] 原: res1 = [] for i in range(1,5): res1.append(i) ...
- python学习那点事---列表生成式实现大小写字母相互转换
题目: 已知列表list=["pYTHON","iS",eASY],要求使用列表生成式实现,生成一个新的列表,要求将大写字母转换为小写字母,小写字母转换为大写字 ...
- Python 函数递归-三元表达式-列表生成式-字典生成式-匿名函数-内置函数
上节课复习: 1. 无参装饰器 def 装饰器名字(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res ...
随机推荐
- nrf52832 连接参数更新过程
ble 连接参数更新过程如下: 一般分三个过程 一 .主机发起连接(带有一个连接参数,一般都是 7.5ms) 二.主机更新连接参数 (举例:NRF CONNECT 安卓app软件 45ms). 三.从 ...
- Codeforces Educational round 58
Ediv2 58 随手AK.jpg D 裸的虚树,在这里就不写了 E 傻逼贪心?这个题过的比$B$都多.jpg #include <cstdio> #include <algorit ...
- python3 的 round 函数的 练习
python3 的 round 函数感觉很别扭,其运算结果与习惯不相符.特记录下来: 代码 ''' python 3的 round 函数 是"四舍六入五成双"的 https://w ...
- 利用OVS+FLOODLIGHT,为数据表添加VLAN_ID和MPLS
话不多说,直接上拓扑: 我这里是用主机h1 (10.0.0.1)ping 主机h2(10.0.0.2) 1.添加VLAN标签 v1: sudo ovs-ofctl add-flow m1-s1 in_ ...
- shell变量常用方法
变量之数组操作: 参考网址:http://www.jb51.net/article/55253.htm #直接赋值 [root@local-]=chengd [root@local-]=xrd [ro ...
- django请求的生命周期
1. 概述 首先我们知道HTTP请求及服务端响应中传输的所有数据都是字符串. 在Django中,当我们访问一个的url时,会通过路由匹配进入相应的html网页中. Django的请求生命周期是指当用户 ...
- 纯 CSS 解决自定义 CheckBox 背景颜色问题
CodePen 需要使用色 #ec6337(当然可以是任意颜色),解决问题:记住密码定制 CheckBox,解释全在注释里 主要使用到 ::before 或 ::after 伪类处理,伪装成内部的那个 ...
- CSS技巧收集——巧用滤镜
最近暴雪一款叫<守望先锋>的游戏火到不行,身边很多人都深受其毒害,虽然博主自己没有买(穷),但是耳濡目染也了解了个大概. 由于之前大致学习了一下 css 滤镜的各种用法,所以心血来潮结合二 ...
- docker之私有仓库镜像管理
一.查看本地镜像 二.给镜像打标记(tag ) [root@node03 ~]# docker tag wordpress:v1 192.168.1.197:5000/wordpress:v1 2.删 ...
- ELK安装部署
一.ELK简介 ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心套件,但并非全部.Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大 ...