推导式

推导式的定义: 通过一行循环判断,遍历一系列数据的方式

推导式的语法:

val for val in Iterable

三种方式:

  [val for val in Iterable]

  {val for val in Iterable}

  {k:v for k,v in Iterable}

列表推导式

1.单循环推导式

将[1,2,3,4,5] -> [3,6,9,12,15]

# 1.单循环推导式 [1,2,3,4,5] -> [3,6,9,12,15]
lst = [1,2,3,4,5]
lst_new = []
for i in lst:
res = i * 3
lst_new.append(res)
print(lst_new) # 改写成推导式
lst = [i*3 for i in lst]
print(lst)

2.带有判断条件的单循环推导式

# 2.带有判断条件的单循环推导式 (只能是单项分支,接在for后面)
lst = [1,2,3,4,5,6,7,8]
lst_new = []
for i in lst:
if i % 2 == 1:
lst_new.append(i)
print(lst_new) # 改写成推导式
lst = [i for i in lst if i % 2 == 1]
print(lst)

3.双循环推导式

# 3. 双循环推导式
lst1 = ["A","B","C","D"]
lst2 = ["X","Y","Z","Q"]
# "谁""谁"
lst_new = []
for i in lst1:
for j in lst2:
strvar = i + "" + j
lst_new.append(strvar)
print(lst_new) # 改写成推导式
lst = [i + "" + j for i in lst1 for j in lst2]
print(lst)

4.带有判断条件的多循环推导式

# 4.带有判断条件的多循环推导式
lst_new = []
for i in lst1:
for j in lst2:
if lst1.index(i) == lst2.index(j):
strvar = i + "" + j
lst_new.append(strvar)
print(lst_new) # 改写成推导式
lst = [ i + "" + j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j) ]
print(lst)

推导式练习题

1.{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式

# 使用等号"="进行拼接
lst = [k + "=" + v for k,v in dic.items()]
print(lst)

2.x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中

# 方法一
lst = [(x,y) for x in range(6) for y in range(6) if x % 2 == 0 and y % 2 == 1]
print(lst) # 方法二
lst = [(x,y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1]
print(lst)

3.使用列表推导式 制作所有99乘法表中的运算

# for前面是一个format字符串的格式化
lst = ["{}*{}={:2d} ".format(i,j,i*j) for i in range(9,0,-1) for j in range(1,i+1) ]
print(lst)

4.求M,N中矩阵和元素的乘积

M = [  [1,2,3], 
     [4,5,6], 
     [7,8,9] ] 

N = [  [2,2,2], 
     [3,3,3], 
     [4,4,4] ] 
=>实现效果1 [2, 4, 6, 12, 15, 18, 28, 32, 36]
=>实现效果2 [[2, 4, 6], [12, 15, 18], [28, 32, 36]]

# 实现思路
M = [[1,2,3],[4,5,6],[7,8,9]]
N = [[2,2,2],[3,3,3],[4,4,4]] """
M[0][0] * N[0][0] => 2
M[0][1] * N[0][1] => 4
M[0][2] * N[0][2] => 6 M[1][0] * N[1][0] => 12
M[1][1] * N[1][1] => 15
M[1][2] * N[1][2] => 18 M[2][0] * N[2][0] => 28
M[2][1] * N[2][1] => 32
M[2][2] * N[2][2] => 36 外层的循环动的慢,内层的循环动的快,
外层的循环动一次,内层的循环动3次,
利用这个规律取出对应下标,乘积即可.
""" # 效果一 [2, 4, 6, 12, 15, 18, 28, 32, 36]
lst = [M[i][j] * N[i][j] for i in range(3) for j in range(3)]
print(lst) # 效果二 [[2, 4, 6], [12, 15, 18], [28, 32, 36]]
# 1 . 先遍历出三个空列表
lst = [ [] for i in range(3) ] => [ [],[],[] ]
# 2 . 把空列表中的数据在通过推导式算出所有内容
lst = [ [M[i][j] * N[i][j] for j in range(3)] for i in range(3) ]
print(lst)

集合推导式

关于集合推导式的一个示例:

1.集合有自动去重的效果

2.用三元表达式+推导式即可实现

"""
案例:
满足年龄在18到21,存款大于等于5000 小于等于5500的人,
开卡格式为:尊贵VIP卡老x(姓氏),否则开卡格式为:普通用户卡老x(姓氏)
把开卡的种类统计出来
"""
listvar = [
{"name":"彭云飞","age":18,"money":10000},
{"name":"夏圣钦","age":19,"money":5100},
{"name":"陈正正","age":20,"money":4800},
{"name":"王添龙","age":21,"money":2000},
{"name":"万潇阳","age":18,"money":20}
] # 常规写法
setvar = set()
for i in listvar:
if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500:
res = "尊贵VIP卡老" + i["name"][0]
else:
res = "普通用户卡老" + i["name"][0]
setvar.add(res)
print(setvar) # 改写成集合推导式
# {三元运算符 + 推导式}
setvar = { "尊贵VIP卡老" + i["name"][0] if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500 else "普通用户卡老" + i["name"][0] for i in listvar }
print(setvar)

字典推导式

1.enumerate

功能:

  枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
参数:

  iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
  start: 可以选择开始的索引号(默认从0开始索引)
返回值:迭代器

enumerate形成字典推导式示例:

from collections import Iterator
lst = ["东邪","西毒","南帝","北丐"] # 基本使用
it = enumerate(lst) # [(0, '东邪'), (1, '西毒'), (2, '南帝'), (3, '北丐')]
print(isinstance(it,Iterator)) # for + next
for i in range(4):
print(next(it))
# list
"""start可以指定开始值,默认是0"""
it = enumerate(lst,start=1)
print(list(it)) # [(1, '东邪'), (2, '西毒'), (3, '南帝'), (4, '北丐')] # enumerate 形成字典推导式 变成字典
dic = { k:v for k,v in enumerate(lst,start=1) }
print(dic) # {1: '东邪', 2: '西毒', 3: '南帝', 4: '北丐'} # dict 强制变成字典
dic = dict(enumerate(lst,start=1))
print(dic) # {1: '东邪', 2: '西毒', 3: '南帝', 4: '北丐'}

2.zip

zip(iterable, ... ...)
  功能:将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中

  参数:iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)

  返回值: 迭代器

  特征:如果找不到对应配对的元素,当前元素会被舍弃

lst1=["Fly","1dao","Hurt","Mojo"]
lst2=["Snow","Song","Giao"]
lst3=["770","JieJ"] it = zip(lst1,lst2,lst3)
print(list(it)) # [('Fly', 'Snow', '770'), ('1dao', 'Song', 'JieJ')]
# zip形成字典推导式 变成字典
lst1=["Fly","1dao","Hurt","Mojo"]
lst2=["Snow","Song","Giao"]
dic={k:v for k,v in zip(lst1,lst2)}
print(dic) # {'Fly': 'Snow', '1dao': 'Song', 'Hurt': 'Giao'}
# dict强制变为字典
dic = dict(zip(lst1,lst2))
print(dic) # {'Fly': 'Snow', '1dao': 'Song', 'Hurt': 'Giao'}

生成器表达式

1.生成器本质是迭代器,允许自定义逻辑的迭代器
2.迭代器和生成器区别:
  迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑
3.生成器可以用两种方式创建:
  (1)生成器表达式 (里面是推导式,外面用圆括号)
  (2)生成器函数 (用def定义,里面含有yield)

4.生成器表达式<=>元组推导式

gen = (i*2 for i in range(1,11))

生成器函数

yield 类似于 return
共同点在于:执行到这句话都会把值返回出去
不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
而return直接终止函数,每次重头调用.
yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用

1.生成器函数的基本语法:

# 定义一个生成器函数
def mygen():
print(111)
yield 1 print(222)
yield 2 print(333)
yield 3 # 初始化生成器函数,返回生成器对象,简称生成器
gen = mygen() # gen是生成器对象(生成器)
print(isinstance(gen,Iterator)) # gen是一个迭代器 # 使用next调用
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)

关于生成器函数的执行流程

代码解析:
初始化生成器函数 -> 生成器(通过next调用)
第一次调用生成器
res = next(gen) => print(111) yield 1 保存当前代码状态14行,并将1这个值返回 print(1) ,等待下一次调用
第二次调用生成器
res = next(gen) => 从上一次保存的状态14行继续向下执行
print(222) yield 2 保存当前代码状态17行,并将2这个值返回 print(2) ,等待下一次调用
第三次调用生成器
res = next(gen) => 从上一次保存的状态17行继续向下执行
print(333) yield 3 保存当前代码状态20行,并将3这个值返回 print(3) ,等待下一次调用
第四次调用生成器
因为没有更多yield返回数据了,所以直接报错.

2.send的用法

next和send区别:
next 只能取值
send 不但能取值,还能发送值
send注意点:
第一个 send 不能给 yield 传值 默认只能写None
最后一个yield 接受不到send的发送值
send 是给上一个yield发送值

def mygen():
print("process start")
res = yield 100
print(res,"内部打印1") res = yield 200
print(res,"内部打印2") res = yield 300
print(res,"内部打印3")
print("process end") # 初始化生成器函数 -> 生成器
gen = mygen()
# 在使用send时,第一次调用必须传递的参数是None(硬性语法),因为第一次还没有遇到上一个yield
'''第一次调用'''
res = gen.send(None) #<=> next(gen)
print(res)
'''第二次调用'''
res = gen.send(101) #<=> next(gen)
print(res)
'''第三次调用'''
res = gen.send(201) #<=> next(gen)
print(res)
'''第四次调用, 因为没有更多的yield返回数据了,所以StopIteration'''
res = gen.send(301) #<=> next(gen)
print(res)

初始化生成器函数,返回生成器对象
第一次调用时,
print("process start")
res = yield 100 记录当前代码状态81行,返回100,等待下一次调用
res = 100 print(100)

第二次调用时,
把101 发送给上一个yield保存的状态81行 res = 101 从81行继续往下走
print(101,"内部打印1")
res = yield 200 记录当前代码状态84行,返回200,等待下一次调用
res = 200 print(200)

第三次调用时,
把201 发送给上一个yield保存的状态84行 res = 201 从84行继续往下走
print(201,"内部打印2")
res = yield 300 记录当前代码状态87行,返回300,等待下一次调用
res = 300 print(300)

3.yield from

将一个可迭代对象变成一个迭代器返回

def mygen():
yield from ["Alan","Fly","Hurt","1dao"] gen = mygen()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))

4.示例:用生成器描述斐波那契数列

"""1 1 2 3 5 8 13 21 34 ... """
"""
yield 1
a,b = b,a+b = 1,1 yield 1
a,b = b,a+b = 1,2 yield 2
a,b = b,a+b = 2,3 yield 3
a,b = b,a+b = 3,5 yield 5
.... """ def mygen(maxlen):
a,b = 0,1
i = 0
while i < maxlen:
yield b
a,b = b,a+b
i+=1 # 初始化生成器函数 -> 生成器
gen = mygen(10) for i in range(3):
print(next(gen))

day14:列表/集合/字典推导式&生成器表达式&生成器函数的更多相关文章

  1. PythonStudy——列表与字典推导式 List and dictionary derivation

    # 快速生成列表或字典的语法糖,且能在生成过程中添加简单的逻辑 # 能被列表推导式推导的数据源必须在循环取值时可以得到一个值 ls = [v for v in range(1, 6)] print(l ...

  2. day12函数,三元表达式 ,列表推导式 ,字典推导式,函数对象,名称空间与作用域,函数的嵌套定义

    复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 # 函数的参数 # 1)实参与形参: # -- 形参:在函数定义时()中出现的参数 # -- 实参:在函 ...

  3. python之三元表达式,列表|字典推导式,函数对象

    #### 三元表达式: 就是if....else...的语法糖 # -- 1) 只能解决if...else...结构,其他if分支结构都不管 # -- 2)一个分支提供一个结果: 如果一个分支提供了多 ...

  4. day14(2)---列表推导式、生成器推导式、字典推导式、三元表达式

    一.列表推导式: ls = [元素表达式 for i in 可迭代对象 if 筛选条件] 案例: # -*- coding: utf-8 -*- '''列表生成式练习''' # 练习一(三元表达式): ...

  5. 周末学习笔记——day02(带参装饰器,wraps修改文档注释,三元表达式,列表字典推导式,迭代器,生成器,枚举对象,递归)

    一,复习 ''' 1.函数的参数:实参与形参 形参:定义函数()中出现的参数 实参:调用函数()中出现的参数 形参拿到实参的值,如果整体赋值(自己改变存放值的地址),实参不会改变,(可变类型)如果修改 ...

  6. python 列表推导式,生成器推导式,集合推导式,字典推导式简介

    1.列表推导式multiples = [i for i in range(30) if i % 2 is 0]names = [[],[]]multiples = [name for lst in n ...

  7. python的各种推导式(列表推导式、字典推导式、集合推导式)

    推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...

  8. Python中的推导式(列表推导式、字典推导式、集合推导式)

    推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(lis ...

  9. 『Python基础-12』各种推导式(列表推导式、字典推导式、集合推导式)

    # 『Python基础-12』各种推导式(列表推导式.字典推导式.集合推导式) 推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的 ...

  10. python笔记3 闭包 装饰器 迭代器 生成器 内置函数 初识递归 列表推导式 字典推导式

    闭包 1, 闭包是嵌套在函数中的 2, 闭包是内层函数对外层函数的变量(非全局变量)的引用(改变) 3,闭包需要将其作为一个对象返回,而且必须逐层返回,直至最外层函数的返回值 闭包例子: def a1 ...

随机推荐

  1. PPT之图表

    1.从数据到信息 同样的数据,通过不同的图样式来呈现不同的突出重点.使用饼状图突出元素占比,使用排序的柱状图突出最大或者最小的元素,使用虚化与实体突出表达重点. 同样的数据,通过不同的关注点突出重点. ...

  2. web.xml文件报错'org.springframework.web.filter.CharacterEncodingFilter' is not assignable to 'javax.servlet.Servlet,jakarta.servlet.Servlet'

    在web.xml文件中出现下列错误:'org.springframework.web.filter.CharacterEncodingFilter' is not assignable to 'jav ...

  3. vscode 远程服务器同步

    1.下载 sftp 2. 在项目目录下新建sftp.json文件 3. 编辑sftp.json文件 { "name": "My Server", "h ...

  4. 几行python代码完美操控手机

    最近一直成谜于python代码带来的便利,今天打算学习下用python代码来控制操作手机,首先需要利用adb,通过安卓调试桥来达到目的,其实也可以用appium来实现,不过appium多数用在自动化测 ...

  5. 深入理解css 笔记(6)

    网格布局:flexbox 彻底改变了网页布局方式,但这只是开始.它还有一个大哥:另一个称作网格布局模块的新规范.这两个规范提供了一种前所未有的全功能布局引擎.跟 flexbox 类似,网格布局也是作用 ...

  6. 转载:VMware Esxi开通SSH功能

    转载:https://www.cnblogs.com/dsl146/p/13739953.html ESXi 5.5是直接安装在物理主机上的一个虚拟机系统,本质上是一个Linux系统.平时可以通过VM ...

  7. CH573 CH582 CH579蓝牙主机(Central)例程讲解一(主机工作流程)

    蓝牙主机,顾名思义,就是一个蓝牙主设备,与从机建立连接进行通信,可以接收从机通知,也可以给从机发送信息,可将Central例程和Peripheral例程结合使用. 蓝牙主机例程的工作流程大致如下: 一 ...

  8. 关于一维数组传入函数的使用 //西电oj214题字符统计

    #include<stdio.h> void count(char str[],int num[]){//形参用[],传递数组首地址后可以直接正常用数组str[i] int i; for( ...

  9. Javaweb项目和Maven项目的相关导包

    Javaweb项目的学习大致需要一下几个导包: 以上几个包需要导入到WEB-INF目录下的lib文件夹里面,主要操作如下: 1.新建一个lib文件夹(在WEB-INF目录下) 2.右键lib文件夹,选 ...

  10. 声网赵斌:RTE 体验提升,新一代 Killer App 将成为现实丨RTE 2022

    一年以来,在疫情及诸多综合因素的推动下,元宇宙.无人驾驶. IoT.电商直播等行业迎来井喷式发展,RTE 实时互动技术也在越来越多的场景中发挥着关键作用.在刚刚过去的 RTE 2022 第八届实时互联 ...