python生成式,列表推导式,lambda,合在一起的大坑
先对如下代码来预测一下结果:
print("=======1=======")
list = [lambda: x for x in range(10)]
for j in range(len(list)):
print(list[j](),end='')
print("=======2=======")
list_2 = [x for x in range(10)]
for i in range(len(list_2)):
print(list_2[i],end='')
结果
9999999999;0123456789
解析
首先在这个问题中我们需要的知识有列表推导式,lambda匿名函数,以及易混项生成式。
先介绍一下易混项生成式:
生成式本质还是生成器,只是写法更简洁;生成器的基本只是在这里简述一下,生成器属于迭代器,查看元素只能一个一个往出取。不能像其他python数据结构如(list,dict等)能整体查看操作。这里对概念就简述这么多,在放一个例子。
list_1 = (x for x in range(10))
while True:
try:
print(next(list_1),end='')
except StopIteration: #弹出StopIteration异常时打印over并终止取生成器的下一个元素
print("over")
break
# 结果 0123456789over
再介绍一下列表推导式
print("=======2=======")
list_2 = [x for x in range(10) if x%2 == 0]
for i in range(len(list_2)):
print(list_2[i],end='')
这是一个列表推导式,列表推导式是python提供的一种生成包含指定元素的列表生成简写方法,是由[列表元素 循环体 条件判断] 三部分构成。
列表推导式和生成器生成式区别
内存占用区别:列表推导式一次产生整个列表的所有元素,构建完整的列表;生成器生成式利用next方法每次生成一个元素。
写法区别:()和[]
匿名lambda函数介绍
- 语法
lambda 参数列表 : 返回值 - 说明
lambda - 关键字
参数列表 - 相当于普通函数的形参列表,变量1,变量2,...
: --> 固定写法
返回值 - 相当于普通函数函数体中的return语句。可以是除了赋值语句以外的任何语句
注意:匿名函数本质还是函数,之前函数中讲的语法绝大多数都适用。(除了通过类型名对参数类型说明不支持)
# 简例
add1 = lambda x, y : x + y
print(add1(1,2))
进入正题说大坑:
print("=======1=======")
list_3 = lambda:[x for x in range(10)]
print(list_3())
print("=======2=======")
i= 0
list = [(lambda: i) for x in range(10)]
for j in range(len(list)):
print(list[j](),end='')#
print("========3======")
list = [(lambda: x) for x in range(10)]
for j in range(len(list)):
print(list[j](),end='')#
print("========4======")
list = [lambda: x for x in range(10)]
for j in range(len(list)):
print(list[j](),end='')
用一组递进写法来详述:
- lambda匿名函数是一个不需要传参返回值时[x for x in range(10)]列表的函数。
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- 利用列表生成式建立了10个lambda匿名函数,函数返回值均是i = 0.
结果:
0000000000
- 利用列表生成式建立了10个lambda匿名函数,函数返回值均是x。由于在生成列表元素的时候,x在循环体中进行了迭代,最后x = 9。所以10个函数的返回值均是9.(加括号方便分清列表中到底是列表推导式还是一个匿名函数)
结果:
9999999999
4. 两个坑,首先匿名函数返回值和列表推导式变量一致!导致函数返回值是执行完推导式后的最后一个迭代的参数(x=9);其次不加括号导致很多朋友认为列表中是一个lambda函数;函数的返回值是x for x in range(10)的推导式,所以得出错误结果,对比1到4就可以清晰地搞清楚关系。还有一个基础的知识点(函数的返回值不能是赋值语句!!!)
结果
9999999999