第十章 迭代、推导和生成
00 min
2024-4-23

 

列表解析式

列表解析式List Comprehension,也叫列表推导式,是一种语法糖
  • 编译器会优化,不会因为简写而影响效率,反而因优化提高效率
  • 减少程序员工作量,减少出错
  • 简化代码,增强可读性
用列表解析式实现上面的功能:
语法:
  • [返回值表达式 for 元素 in 可迭代对象 if 条件]
  • 使用中括号[],内部是for循环,if条件可选;
  • 先for循环遍历元素,遍历的元素再通过if条件语句筛选过滤,过滤出来的元素再给到返回值表达式
进阶:
 

集合解析式

集合解析式和列表解析式的语法基本一样, 不同指出就是将列表的中括号改为大括号即可
语法:
  • {返回值 for 元素 in 可迭代对象 if 条件}
  • 列表解析式中的中括号换成大括号即可
  • 返回一个集合

字典解析式

语法:
  • {k(i):v(i) for i in 可迭代对象 if 条件}
  • 集合解析式中的返回值变为键值对, 键和值都是由i定义
  • 返回一个字典
 

生成器表达式

语法:
  • (返回值 for 元素 in 可迭代对象 if 条件)
  • 列表解析式中的中括号换成小括号即可
  • 返回一个生成器对象
 
和列表解析式区别:
  • 生成器表达式是按需计算(或称惰性求值、延迟计算),需要的时候才计算值
  • 列表解析式是立即返回值
 
生成器对象(三者包含与被包含关系:可迭代对象>迭代器>生成器)
  • 可迭代对象
  • 特殊的迭代器
注:range对象是惰性求值,但不是生成器;列表是可迭代对象,不是惰性求值,也不是迭代器,更不是生成器。
 

生成器表达式和列表解析式对比

生成器表达式
列表解析式
延迟计算
立即计算
返回可迭代对象迭代器
返回可迭代列表,不是迭代器
只能迭代一次
可反复迭代
  • 计算方式
    • 生成器表达式延迟计算,列表解析式立即计算
  • 内存占用
    • 但从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表
    • 生成器没有数据,内存占用极少,但是使用的时候,是一个个返回数据,不会为所有元素立即占用大量内存
    • 列表解析式构造新的列表需要立即占用掉内存
  • 计算速度
    • 但从计算时间看,生成器表达式耗时非常短,列表解析式耗时长
    • 但生成器本身并没有返回任何值,只返回了一个生成器对象
    • 列表解析式构造并返回一个新的列表
 

集合解析式

语法
  • {返回值表达式 for 元素 in 可迭代对象 if 条件}
  • 列表解析式中的中括号改成大括号就变成了集合解析式
  • 立即返回一个集合
 

字典解析式

语法
  • {key:value for key in iterable1 for value in iterable2 if cond}
  • {key:value for var in iterable if cond}
  • 立即返回一个字典
 

总结

  • Python2引入列表解析式
  • Python2.4引入生成器表达式
  • Python3引入集合、字典解析式,并迁移到了2.7
一般来说,应该多应用解析式,简短、高效。如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环。
生成器和迭代器是不同的对象,但都是可迭代对象。
如果不需要立即获得所有可迭代对象的元素,在Python3中,推荐使用惰性求值的迭代器。