day14.推导式与生成器
一、列表推导式
'''通过一行循环判断,遍历一系列数据的方式'''
"""
推导式的语法:
val for val in Iterable
三种方式:
[val for val in Iterable]
{val for val in Iterable}
{k:v for k,v in Iterable}
"""
1、向列表里插入100条数据
# 列表里面需要100条数据
lst = []
for i in range(1,101):
lst.append(i)
print(lst)
改写成推导式
# 基本语法
lst = [i for i in range(1,101)]
print(lst)
2、[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)
3、带有判断条件的单循环推导式 (只能是单项分支,接在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)
4、双循环推导式
lst1 = ["李博伦","高云峰","孙致和","葛龙"]
lst2 = ["李亚","刘彩霞","刘子豪","刘昕"]
# "谁""谁"
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)
5、带有判断条件的多循环推导式
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)
6、推导式练习
"""
(1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式
(2).把列表中所有字符变成小写 ["ADDD","dddDD","DDaa","sss"]
(3).x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中
(4).使用列表推导式 制作所有99乘法表中的运算
(5)#求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]]
"""
# 常规
dic = {'x': 'A', 'y': 'B', 'z': 'C' }
lst = []
for k,v in dic.items():
strvar = k + "=" + v
lst.append(strvar)
print(lst) # 改写推导式
lst = [k + "=" + v for k,v in dic.items()]
print(lst)
(1)
lst = ["ADDD","dddDD","DDaa","sss"]
lst_new = []
# 常规
for i in lst:
lst_new.append(i.lower())
print(lst_new) # 改写推导式
lst = [i.lower() for i in lst ]
print(lst)
(2)
"""
0 2 4
1 3 5
"""
# 方法一
lst = []
for x in range(6):
for y in range(6):
if x % 2 == 0 and y % 2 == 1:
lst.append((x,y))
print(lst) lst = [(x,y) for x in range(6) for y in range(6) if x % 2 == 0 and y % 2 == 1]
print(lst) # 方法二
lst = []
for x in range(6):
if x % 2 == 0:
for y in range(6):
if y % 2 == 1:
lst.append((x,y))
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)
for i in range(9,0,-1):
for j in range(1,i+1):
print("{}*{}={:2d} ".format(i,j,i*j),end="")
print() 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 = [[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次,
利用这个规律取出对应下标,乘积即可.
"""
lst = []
for i in range(3):
for j in range(3):
print(i,j)
res = M[i][j] * N[i][j]
lst.append(res)
print(lst) # 改写推导式[效果一]
lst = [M[i][j] * N[i][j] for i in range(3) for j in range(3)]
print(lst) # 改写推导式[效果二] # 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) """
常规写法:
M = [[1,2,3],[4,5,6],[7,8,9]]
N = [[2,2,2],[3,3,3],[4,4,4]]
lst2 = []
for i in range(3):
lst = []
for j in range(3):
lst.append( M[i][j] * N[i][j] )
lst2.append(lst)
print(lst2)
"""
(5)
二、集合推导式
"""
案例:
满足年龄在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)
三、字典推导式
"""
enumerate(iterable,[start=0])
功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
参数:
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
start: 可以选择开始的索引号(默认从0开始索引)
返回值:迭代器
"""
from collections import Iterator
lst = ["东邪","西毒","南帝","北丐"] # 基本使用
it = enumerate(lst)
print(isinstance(it,Iterator))
for + next
# for + next
for i in range(4):
print(next(it)) # (0, '东邪')
# (1, '西毒')
# (2, '南帝')
# (3, '北丐')
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: '北丐'}
四、zip
"""
zip(iterable, ... ...)
功能: 将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
返回: 迭代器 特征: 如果找不到对应配对的元素,当前元素会被舍弃
"""
# 基本使用
lst1 = ["晏国彰","刘子涛","郭凯","宋云杰"]
lst2 = ["刘有右柳翔","冯雍","孙志新"]
lst3 = ["周鹏飞","袁伟倬"]
# it = zip(lst1,lst2)
it = zip(lst1,lst2,lst3)
print(isinstance(it,Iterator))
print(list(it))
"""
[('晏国彰', '刘有右柳翔'), ('刘子涛', '冯雍'), ('郭凯', '孙志新')]
[('晏国彰', '刘有右柳翔', '周鹏飞'), ('刘子涛', '冯雍', '袁伟倬')]
"""
1、zip 形成字典推导式 变成字典
lst1 = ["晏国彰","刘子涛","郭凯","宋云杰"]
lst2 = ["刘有右柳翔","冯雍","孙志新"]
dic = { k:v for k,v in zip(lst1,lst2) }
print(dic) # dict 强制变成字典
dic = dict(zip(lst1,lst2))
print(dic)
五、生成器表达式
"""
#生成器本质是迭代器,允许自定义逻辑的迭代器 #迭代器和生成器区别:
迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑 #生成器可以用两种方式创建:
(1)生成器表达式 (里面是推导式,外面用圆括号)
(2)生成器函数 (用def定义,里面含有yield)
"""
from collections import Iterator,Iterable
# 生成器表达式
gen = (i*2 for i in range(1,11))
print(isinstance(gen,Iterator)) # next
res = next(gen)
print(res) # for
for i in gen:
print(i) # for + next
gen = (i*2 for i in range(1,11))
for i in range(3):
res = next(gen)
print(res) # list
print("<=====>")
res = list(gen)
print(res)
六、生成器函数
"""
# 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()
print(isinstance(gen,Iterator)) # 使用next调用
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
# res = next(gen) error
# 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、代码优化
def mygen():
for i in range(1,101):
yield "该球衣号码是{}".format(i)
# 初始化生成器函数 -> 生成器
gen = mygen() # for + next 调用数据
for i in range(50):
res = next(gen)
print(res)
print("<====>")
for i in range(30):
res = next(gen)
print(res)
3、send用法
"""
### 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'''
"""
# 代码解析:
初始化生成器函数,返回生成器对象
第一次调用时,
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)
"""
代码解析
4、yield from : 将一个可迭代对象变成一个迭代器返回
def mygen():
yield from ["马生平","刘彩霞","余锐","晏国彰"] gen = mygen()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
5、用生成器描述斐波那契数列
"""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))
七、练习
"""
者 创建于 4天前
# 1.用推导式写如下程序
(1)构建如下列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
(2)lst = ['alex', 'WuSir', '老男孩', '神秘男孩'] 将lst构建如下列表:['alex0', 'WuSir1', '老男孩2', '神秘男孩3']
(3)构建如下列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
(4)求出50以内能被3整除的数的平方,并放入到一个列表中。
(5)M = [[1,2,3],[4,5,6],[7,8,9]], 把M中3,6,9组成新列表
(6)构建如下列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
(7)过滤掉长度小于3的字符串列表 , 并转换成大写字母
(8)除了大小王,里面有52项,每一项是一个元组,请返回如下扑克牌列表[('红心','2'),('草花','J'), …('黑桃','A')] # 2.用推导式写如下程序
lst1 = {
'name':'alex',
'Values':[
{'timestamp': 1517991992.94,'values':100,},
{'timestamp': 1517992000.94,'values': 200,},
{'timestamp': 1517992014.94,'values': 300,},
{'timestamp': 1517992744.94,'values': 350},
{'timestamp': 1517992800.94,'values': 280}
]
}
将lst1 转化成如下lst2:
lst2 = [
[1517991992.94, 100],
[1517992000.94, 200],
[1517992014.94, 300],
[1517992744.94, 350],
[1517992800.94, 280]
] # 3.读取一个文件所有内容,通过生成器调用一次获取一行数据.
# 4.将普通求和函数改写成yield写法
def add(a,b):
return a + b
"""
print([i * 2 for i in range(10)])
1 (1)
print([j + str(i) for i in range(4) for j in lst if i == lst.index(j)])
1 (2)
print([(i, i + 1) for i in range(6)])
1(3)
print([i * i for i in range(50) if i % 3 == 0])
1(4)
# 方法一
print([j for i in m for j in i if i.index(j) == 2])
# 方法二-
print([i[2] for i in m])
1(5)
print(['python' + str(i) + '期' for i in range(1, 11)])
1(6)
lst = ['', 'ra', 'da', '', 'das']
print([i.upper() for i in lst if len(i) >= 3])
1(7)
lst = ['红心', '红桃', '黑桃', '草花']
print([(i, j) for j in range(1, 14) for i in lst])
1(8)
lst1 = {
'name':'alex',
'Values':[
{'timestamp': 1517991992.94,'values':100,},
{'timestamp': 1517992000.94,'values': 200,},
{'timestamp': 1517992014.94,'values': 300,},
{'timestamp': 1517992744.94,'values': 350},
{'timestamp': 1517992800.94,'values': 280}
]
} ret = [[lst1['Values'][i]['timestamp'],lst1['Values'][i]['values']] for i in range(5)]
print(ret)
2
with open('1.txt',mode='r+',encoding='utf-8') as f:
res = f.readlines()
print(res)
def func1():
for i in range(len(res)):
yield res[i] ret = func1()
print(next(ret))
print(next(ret))
print(next(ret))
3
def add(a,b):
yield a+b
res = add(1,2)
print(res.__next__())
4
day14.推导式与生成器的更多相关文章
- python之三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数
一 三元表达式.列表推导式.生成器表达式 一 三元表达式 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(r ...
- python基础17_列表推导式 vs 生成器表达式
[ ] 列表推导式,是用简单的语法来生成列表, ( ) 生成器表达式,是用简单的语法创建个生成器. 外观上仅括号不一样. 虽然写起来方便,但是读起来稍显费力,另外,不易调试. # 列表推导式 prin ...
- python基础知识15---三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数
阅读目录 一 三元表达式.列表推导式.生成器表达式 二 递归与二分法 三 匿名函数 四 内置函数 五 阶段性练习 一. 三元表达式.列表推导式.生成器表达式 1 三元表达式 name=input('姓 ...
- Python_列表推导式_生成器的表达式_各种推导式_40
列表推导式: #列表推导式: egg_list = [] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list) egon egg_ ...
- Python_迭代器、生成器、列表推导式,生成器表达式
1.迭代器 (1)可迭代对象 s1 = ' for i in s1: print(i) 可迭代对象 示例结果: D:\Python36\python.exe "E:/Python/课堂视频/ ...
- Python之推导式、生成器表达式
l = [i for i in range(10)] print(l) l1 = ['选项%s'%i for i in range(10)] print(l1) 1.把列表解析的[]换成()得到的就是 ...
- python全栈开发 生成器 :生成器函数,推导式及生成器表达式
python 全栈开发 1.生成器函数 2.推导式 3.生成器表达式 一.生成器函数 1.生成器: 生成器的本质就是迭代器 (1)生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), ...
- python 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数
http://www.cnblogs.com/linhaifeng/articles/7580830.html 三元表达式.列表推导式.生成器表达式.递归.匿名函数.内置函数
- python 三元表达式、列表推导式、生成器表达式
一 三元表达式.列表推导式.生成器表达式 一 三元表达式 name=input('姓名>>: ') res='mm' if name == 'hahah' else 'NB' print( ...
随机推荐
- 不用加减乘除做加法(剑指offer-48)
题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 题目解析 首先看十进制是如何做的: 5+7=12,三步走 第一步:相加各位的值,不算进位,得到2. 第二步:计 ...
- day50 前端入门
目录 一.引子 1 前端学习的历程 2 浏览器与http协议 2.1 浏览器窗口输入网址回车后发生了几件事 2.2 http协议 二.html入门 1 标签的分类 2 head内常用的标签 3 bod ...
- (三)学习了解OrchardCore笔记——灵魂中间件ModularTenantContainerMiddleware的第一行①的模块部分
了解到了OrchardCore主要由两个中间件(ModularTenantContainerMiddleware和ModularTenantRouterMiddleware)构成,下面开始了解Modu ...
- 如何用HMS Nearby Service给自己的App添加近距离数据传输功能
当你给朋友发送手机资料时,过了很久进度条却动也不动:当你想发送大文件给同事时,仅一个文件就用光了你所有流量:当你跟朋友乘坐飞机时想一起玩游戏时,却因没有网络无奈放弃. 们生活中似乎经常能遇到这 ...
- JavaScript:父页面与Iframe页面方法互调
父页面调用Iframe页面中的函数 以上是父页面中定义的iframe,注意添加name属性 在父页面中调用mapFrame的ShowMyLocation方法 Iframe页面调用父页面的方法 直接在I ...
- 全栈的自我修养: 003Axios 的简单使用
全栈的自我修养: Axios 的简单使用 You should never judge something you don't understand. 你不应该去评判你不了解的事物. 全栈的自我修养: ...
- Controller怎么接收Ajax传来的data
var json = { "VendorId": strVendorId, "VendorName": strVendorName, "Remark& ...
- java io流根据url读取图片
//获取图片大小 public void readFileSize(String url,HttpServletRequest request){ //根路径 File file = new File ...
- Java 并发队列 BlockingQueue
BlockingQueue 开篇先介绍下 BlockingQueue 这个接口的规则,后面再看其实现. 首先,最基本的来说, BlockingQueue 是一个先进先出的队列(Queue),为什么说是 ...
- Docker 概念-1
阅读本文大概需要15分钟,通过阅读本文你将知道一下概念: 容器 什么是Docker? Docker思想.特点 Docker容器主要解决什么问题 容器 VS 虚拟机 Docker基本概念: 镜像(Ima ...