Skip to content

Latest commit

 

History

History
281 lines (199 loc) · 7.66 KB

178-253313-[专业选修]列表推导式_list_comprehension.sy.md

File metadata and controls

281 lines (199 loc) · 7.66 KB
show version enable_checker
step
1.0
true

列表推导式

回忆

  • 这次研究了帮助手册中的 for 语句
  • 深入理解
  • for 还有什么可玩的么?🤔

图片描述

列表生成

图片描述

  • 这个列表的生成过程非常简单
  • 但是我们可以用一种更简明的方式建立列表

列表推导式

  • 这个东西可以用简单一句话来实现

图片描述

  • 这看起来很好理解
  • 这就是列表推导式
  • 我们去帮助里面查看一下

帮助手册

图片描述

  • 他举的例子是这样的
  • 一个求平方的列表推导式
  • 列表推导式的英文是 List Comprehensions
  • 列表的理解方法
  • 其实是一种语法糖
  • 那什么是语法糖呢

语法糖

  • 糖我们都知道

图片描述

  • 那这个糖和语法有什么关系呢?

图片描述

  • 语法糖可以让语法变甜
  • 也就是说让编程人感觉到愉悦
  • 简单来说

图片描述

  • 代码本可以用原来的传统的方式可以写出来
  • 但是现在有这么一种很甜的写法
  • 让人写起来很快、而且可读性很强
  • 就问你用不用
  • 作为语言编译器、解释器的开发者肯定不会由衷欢迎语法糖
  • 因为这会增大语言编译的难度
  • 但是一旦实现了语法糖的功能
  • 语法糖会让编程工作更快速
  • 而且不会降低运行效率

图片描述

  • 而且语法糖普及之后
    • 如果你不懂这块糖
    • 看起代码来反而会吃力
  • 我的建议是
    • 首先能看懂
    • 至于写不写语法糖的代码
    • 我们不去追求
    • 把基本功练好最重要

图片描述

  • 回到我们的列表推导式

继续推导

图片描述

  • 我们可以对于原来迭代器里面的进行任何运算和操作
  • 然后得到一个列表
  • 我们也可以对这里列表做一些函数操作
  • 那我们可以对于迭代器里面内容进行筛选吗?

筛选

图片描述

  • 这样就可以提前对于迭代器进行筛选了
  • 那我们可以对于最终结果进行筛选吗?
  • 思考一下
  • 这个应该怎么写?

对结果筛选

图片描述

  • 这样可以对于结果进行筛选
  • 如果既要对迭代器筛选
  • 又要对结果进行筛选呢?

继续推导

图片描述

  • 这就是语法糖
  • 吃了糖也不忘粮
  • 如果我们用传统 for 语句应该怎么写呢?

传统写法

图片描述

  • 其实只是写法不同而已
  • 最终还是要 cpu 去具体执行指令
  • 本质上是一样的
  • 列表推导式还有什么好玩的么?

括号问题

图片描述

  • 如果需要返回元组
    • 小括号是不能省的
  • 我们可以看到可以对于列表推导项进行各种运算和函数
  • 可以来点更复杂的么?

复杂函数的列表推导式

图片描述

  • 这个推导可以来二重么?

二重推导

图片描述

  • 这个例子看起来还是很明确的
  • 要注意列表项是 tuple 元组
  • 元组的小括号还是不能省略的
  • 如果本身的列表就是二重列表的话
  • 会如何呢?

分层推导

图片描述

  • 二重列表可以先分行
  • 然后分列
  • 这样就可以分层地推导出来了
  • 我能否实现一个二维数组的转置呢?

二维数组的转置

图片描述

图片描述

  • 这样转置是成功的
  • 可以把这个嵌套式的列表推导式转化为普通的 for 语句么?
  • 先扒一层

扒一层

图片描述

  • 运行结果没有问题
  • 可以再扒一层糖衣么?

扒开了

图片描述

  • 这样就是最传统的写法了
  • 相对来说传统的写法更明确
  • 语法糖比较唬人
  • 比较甜
  • 我们一定要能看懂他就可以了
  • 其实最甜的还不是语法糖
  • 想想我们其实以前做过转置

zip 缝合

  • list(zip(*matrix))
  • 更简单就搞定了
  • 不过这个不是语法糖
  • 而是 zip 函数
  • 其实函数就是糖
    • 是很甜的东西
  • 函数可能是
    • 系统自带的
    • 我们导入的
    • 甚至我们自己写的

图片描述

几个例子

print([x[0] for x in [(a[i][0], a.append([a[i][1], a[i][0]+a[i][1]])) for a in ([[1, 1]], ) for i in range(30)]])
print('\n'.join([''.join([('IloveU'[(x-y)%len('IloveU')]if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else' ')for x in range(-30,30)])for y in range(15,-15,-1)]))
print('\n'.join([' '.join(['%s*%s=%-2s' % (y, x, x*y) for y in range(1, x+1)]) for x in range(1, 10)]))
  • 这些例子可以转化为普通的
  • 不加糖的格式么?

图片描述

不加糖的IloveU

for y in range(15, -15, -1):#表示从15- -15每隔一个单位取一次值,
    ls=[]
    for x in range(-30, 30):
        tp=((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3
        if tp<=0:  ##点在图像内部
            a=''.join('IloveU'[(x - y) % 6]) #加字母
        else:   ##点在图像外部
            a=''.join(' ')
        ls.append(a)
    s=''.join(ls)
    print(s)
  • 更通用的格式
text = "IloveU"
for y in range(15, -15, -1):#表示从15- -15每隔一个单位取一次值,
    ls=[]
    for x in range(-30, 30):
        tp=((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3
        if tp<=0:  ##点在图像内部
            a=''.join(text[(x - y) % len(text)]) #加字母
        else:   ##点在图像外部
            a=''.join(' ')
        ls.append(a)
    s=''.join(ls)
    print(s)
  • 可以把text换成任意字符串
  • 甚至可以把emoji加进去

总结

  • 这次研究了列表推导式
  • 列表推导式是一种语法糖
  • 我们至少要能看得懂这颗语法糖
    • 可以对于推导项进行筛选
    • 可以对于推导结果进行筛选
    • 也可以把两个推导复合到一起
  • 所有列表推导式都可以写成原始的 for 语句的形式

图片描述

  • 除了列表可以推导之外
  • 其他的数据结构可以进行推导么?
    • 序列类的有列表推导式
    • 集合类的有 set 推导式么?🤔
    • 映射类的有 dict 推导式么?🤔
  • 下次再说 👋