列表解析式
举例:
1.生成一个列表,元素0~9,对每一个元素自增1后求平方返回新列表
x = []
for i in range(10):
x.append(i+1)
print(x)
解析式写法:[i+1 for i in range(10)]
语法:
[返回值 for元素 in 可迭代对象 if 条件]
使用中括号[],内部是for循环,if条件语句可选
返回一盒新的列表
列表解析式是一种语法糖
编译器会优化,不会因为简写而影响效率,反而因优化提高了效率
减少程序员,减少出错
简化了代码,当可读性增强
举例:
获取10以内的偶数
even = []
for x in range(10):
if x % 2 == 0 :
even.append(X)
even = [x for x in range if x%2==0]
列表解析进阶
[expr for item in iterable if cond1 if cond2]
等于
ret = []
for item in iterable:
if cound1:
if cound2:
ret.append(expr)
20以内,即能被2整除又能被3整除的数
[i for i in range if i%20 and i%30]
[i for i in range if i%20 if i%30]
列表解析进阶:
[expr for i in iterable1 for j in iterable2]
等价于
ret = []
for i in iterable1:
for j in iterable2:
ret.append(expr)
[(x,y) for x in ‘abcde’ for y in range (3)]
[[x ,y] for x in ‘abcde’ for y in range (3)]
[{x:y} for x in ‘abcde’ for y in range (3)]
集合解析式
语法
{返回值 for 值 in 可迭代对象 if 条件}
列表解析式的中括号换成大括号{}就行了
立即返回一个集合
{x for x in range(10)}
字典解析式
{返回值 for 值 in 可迭代对象 if 条件}
列表解析式的中括号换成大括号{}就行了
使用key:value形式
立即返回一个字典
{x:x for x in range(10)}
{x:[x,x+1] for x in range(10)}
{(x,):x for x in range(10)}
生成器表达式Generator expression
语法:
(返回值 for 元素 in 可迭代对象 if 条件)
列表解析式的中括号换成小括号就行了
返回一个生成器
和列表解析式的区别
生成器表达式是按需计算(或称惰性计算 延迟计算),需要的时候才计算值
列表解析式是立即返回值
生成器:
可迭代对象
迭代器
生成器表达式**
g = (i for i in range(1,11))
next(g)
for x in g:
print(x)
for x in g:
print(x)
延迟计算
返回迭代器
迭代器从前到后走,走完一遍后,就失效,不能回头
跟列表解析式对比:
g = [i for i in range(1,11)]
for x in g:
print(x)
for x in g:
print(x)
立即计算
返回的不是迭代器,返回的说可迭代对象列表
可以重复迭代
生成器表达式和列表解析式的对比
计算方式
生成器表达式是延迟计算(惰性计算),列表解析式是立即计算
内存占用
单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
生成器没有数据,内存占用极少,它是使用时一个个返回数据.如果将这些返回的数据合起来和列表解析式差不多.它不需要立即占用这么多内存
列表解析式构造新的列表需要立即占用内存,不管你是否立即使用全部数据
计算速度
单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长
生成器本身本身并没有返回任何值,只返回了一个生成器对象
列表解析式构造并返回了一个新的列表,所以看起来耗时了
总结
python2 引入列表解析式
python2.4 引入生成器表达式
python3 引入集合 字典解析式,并迁移到2.7
应该多用解析式,简短 高效
如果一个解析式非常复杂,难以读懂,可以考虑拆解成for循环
生成器和迭代器是不同的对象,但都式可迭代对象
可迭代对象范围很大,都可以使用for循环遍历