解析式和生成器表达式

列表解析式

列表解析式List Comprehension,也叫列表推导式

#生成一个列表,元素0-9,将每个元素加1后的平方值组成新的列表
x = []
for i in range(10):
x.append((i+1)**2)
print(x
# 列表解析式
[(i+1)**2 for i in range(10)]

语法

  • [返回值 for 元素 in 可迭代对象 if 条件]

  • 使用中括号[],内部是for循环,if条件语句可选

  • 返回一个新的列表

列表解析式是一种语法糖

  • 编译器会优化,不会因为简写而影响效率,反而因优化提高了效率

  • 减少程序员工作量,减少出错

  • 简化了代码,增强了可读性

[expr for item in iterable if cond1 if cond2]
等价于
ret = []
for item in iterable:
   if cond1:
if cond2:
ret.append(expr)
#
[expr for i in iterable1 for j in iterable2 ]
等价于
ret = []
for i in iterable1:
   for j in iterable2:
ret.append(expr)
# 请问下面3种输出各是什么?为什么
[(i,j)  for i in range(7) if i>4 for j in range(20,25) if j>23]
[(i,j)  for i in range(7) for j in range(20,25) if i>4 if j>23]
[(i,j)  for i in range(7) for j in range(20,25) if i>4 and j>23]

集合解析式

语法

  • {返回值 for 元素 in 可迭代对象 if 条件}

  • 列表解析式的中括号换成大括号{}就变成了集合解析式

  • 立即返回一个集合

{(x, x+1) for x in range(10)}
{[x] for x in range(10)} # 可以吗?

字典解析式

语法

  • {key:value for 元素 in 可迭代对象 if 条件}

  • 列表解析式的中括号换成大括号{},元素的构造使用key:value形式

  • 立即返回一个字典

{x:(x,x+1) for x in range(10)}
{x:[x,x+1] for x in range(10)}
{(x,):[x,x+1] for x in range(10)}
{[x]:[x,x+1] for x in range(10)}
# {str(x):y for x in range(3) for y in range(4)} # 输出多少个元素?

生成器表达式

语法

  • (返回值 for 元素 in 可迭代对象 if 条件)

  • 列表解析式的中括号换成小括号就行了

  • 返回一个生成器对象

和列表解析式的区别

  • 生成器表达式是按需计算(或称惰性求值延迟计算),需要的时候才计算值

  • 列表解析式是立即返回值

生成器对象

  • 可迭代对象

  • 迭代器

生成器表达式 列表解析式
延迟计算 立即计算
返回可迭代对象迭代器,可以迭代 返回可迭代对象列表,不是迭代器
只能迭代一次 可反复迭代

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

  • 计算方式

    • 生成器表达式延迟计算,列表解析式立即计算
  • 内存占用

    • 单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表

    • 生成器没有数据,内存占用极少,使用的时候,一次返回一个数据,只会占用一个数据的空间

    • 列表解析式构造新的列表需要为所有元素立即占用掉内存

  • 计算速度

    • 单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长

    • 但生成器本身并没有返回任何值,只返回了一个生成器对象

    • 列表解析式构造并返回了一个新的列表

总结

  • Python2 引入列表解析式

  • Python2.4 引入生成器表达式

  • Python3 引入集合、字典解析式,并迁移到了2.7

一般来说,应该多应用解析式,简短、高效。如果一个解析式非常复杂,难以读懂,要考虑拆解成for循环。

生成器和迭代器是不同的对象,但都是可迭代对象。

如果不需要立即获得所有可迭代对象的元素,在Python 3中,推荐使用惰性求值的迭代器。

内建函数 函数签名 说明
sorted sorted(iterable[, key][, reverse]) 默认升序,对可迭代对象排序
# 排序一定是容器内全体参与
print(sorted([1,2,3,4,5]))
print(sorted(range(10, 20), reverse=True))
print(sorted({'a':100, 'b':'abc'}))
print(sorted({'a':100, 'b':'abc'}.items()))
print(sorted({'a':'ABC', 'b':'abc'}.values(), key=str, reverse=True))
print(sorted({'a':2000, 'b':'201'}.values(), key=str))
print(sorted({'a':2000, 'b':'201'}.values(), key=int))

练习

  • 给出3个整数,使用if语句判断大小,并升序输出
def sorter(x,y,z):
if x>y: #x,y
if x>z: #(x,(z.y))
if y>z:
return x,y,z
else:
return z,z,y
else: # y,x
if y>z: #(y,(x,z))
if x>z:
return y,x,z
else:
return y,z,x
#或
def sorter(x,y,z):
return sorted((x,y,z),key=int,reverse=False)
  • 有一个列表lst = [1,4,9,16,2,5,10,15],生成一个新列表,要求新列表元素是lst相邻2项的和
if __name__ == '__main__':
lst = [1,4,9,16,2,5,10,15]
print([lst[i]+lst[i+1] for i in range(len(lst)-1)])
  • 随机生成100个产品ID,ID格式如下

  • 顺序的数字6位,分隔符点号,10个随机小写英文字符

  • 例如 000005.xcbaaduixy

import random
import string if __name__ == '__main__':
alphabet=string.ascii_lowercase
for i in range(100):
print('{:0>6}.{}'.format(i,''.join(random.choices(alphabet,k=10))))

05.python解析式与生成器表达式的更多相关文章

  1. python 特别的生成器表达式

    Ⅰ起因 学习python的同学通常会遇到这样一道经典生成器测试题: def gen(): for i in range(4): yield i base = gen() for n in (2,10) ...

  2. 详解Python中的生成器表达式(generator expression)

    介绍 1.生成器表达式(generator expression)也叫生成器推导式或生成器解析式,用法与列表推导式非常相似,在形式上生成器推导式使用圆括号(parentheses)作为定界符,而不是列 ...

  3. Python 解析式、生成器

    标准库datetime datetime模块 对日期.时间.时间戳的处理 datetime类 类方法 today() 返回本地时区当前时间的datetime对象 now(tz=None) 返回当前时间 ...

  4. python基础之生成器表达式形式、面向过程编程、内置函数部分

    生成器表达式形式 直接上代码 1 # yield的表达式形式 2 def foo(): 3 print('starting') 4 while True: 5 x=yield #默认返回为空,实际上为 ...

  5. 详解python中的生成器表达式

    什么是生成器表达式 还记得列表解析吗?我们把[]换成()就变成生成器表达式了. g = (x for x in [1, 2, 3, 4]) print(g) # <generator objec ...

  6. Python - 列表解析式/生成器表达式

    列表解析式: [expr for iter_var in iterable if cond_expr] 生成器表达式: (expr for iter_var in iterable if cond_e ...

  7. 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】

    Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...

  8. Python之路(第十篇)迭代器协议、for循环机制、三元运算、列表解析式、生成器

    一.迭代器协议 a迭代的含义 迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 b为何要有迭代器? 对于序列类型:字符串.列表 ...

  9. python全栈开发-前方高能-生成器和生成器表达式

    python_day_13 今日主要内容1. 生成器和生成器函数生成器的本质就是迭代器生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 生成器函数: 函数中 ...

随机推荐

  1. Redis哨兵 部署和配置

    目录 一.哨兵简介 哨兵介绍 哨兵原理 二.哨兵部署 环境介绍 哨兵配置 三.使用验证 一.哨兵简介 哨兵介绍 Sentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在 ...

  2. IT服务生命周期

    一.概述 IT服务生命周期由规划设计(Pianning&Design).部署实施(Implementing).服务运营(Opera,tion).持续改进(Improvemenit)和监督管理( ...

  3. tableau添加参考线

    一.将数据窗口切换至分析窗口-点击自定义-参考线 二.出现编辑参考线和参考区间的界面(整个表指的是整个视图,每区指的是如下2018就是一个区,每单元格指的是横轴的最小值) 三.我们分别为每区添加最大值 ...

  4. 【紧急】继续折腾,Log4j再发2.1.6,强烈建议升级

    背景 继前天正式发布的2.15.0之后,Apache log4j 2 团队宣布 Log4j 2.16.0 发布! 由于SLF4J适配兼容性的中断,Log4j 现在发布两个版本的SLF4J to Log ...

  5. SpringBoot使用 MyBatis Plus 实现物理分页查询

    一.分页配置在MyBatis Plus 可以直接使用selectPage这样的分页,但返回的数据确实是分页后的数据,但在控制台打印的SQL语句其实并没有真正的物理分页,而是通过缓存来获得全部数据中再进 ...

  6. 慢 SQL 优化

    # 导致SQL执行慢的原因 1. 硬件问题.如网络速度慢,内存不足,I/O吞吐量小,磁盘空间满了等. 2. 没有索引或者索引失效.(一般在互联网公司,DBA会在半夜把表锁了,重新建立一遍索引,因为当你 ...

  7. Solon 1.6.11 发布。类似 Spring 的生态体系

    关于官网 千呼万唤始出来: https://solon.noear.org .整了一个月多了,总体样子有了...还得不断接着整! 关于 Solon Solon 是一个轻量级应用开发框架.支持 Web. ...

  8. Vue的安装及使用(Vue的三种安装使用方式)

    vue是一个JavaMVVM库,是一套用于构建用户界面的渐进式框架,是初创项目的首选前端框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计.它是轻量级的,它有很多独立的功能或库,我们 ...

  9. 查看电脑内存是ddr3还是ddr4

    内存不够用了 要加个内存 但是不想拆机 怎么知道自己电脑是第几代内存呢? 怎么知道频率呢? 1.运行cmd 2.输入wmic回车 3.输入memorychip回车 4.往右拉找到Speed Statu ...

  10. 涂鸦智能 dubbo-go 亿级流量的实践与探索

    涂鸦智能 dubbo-go 亿级流量的实践与探索 dubbo 是一个基于 Java 开发的高性能的轻量级 RPC 框架,dubbo 提供了丰富的服务治理功能和优秀的扩展能力.而 dubbo-go 在 ...