13py

### 推导式 : 用一行循环判断遍历出一系列数据的方式

“”"
推导式在使用时,只能用for循环和判断,
而且判断是能是单项判断
“”"

lst = [1,2,3,4,5,6,7,8,9]
lst_new = []
for i in range(1,51):
lst_new.append(i)
print(lst_new)
#基本语法
lst = [i for i in range(1,51)]
print(lst)

(1)普通推导式

[1,2,3,4] => [2,8,24,64]

lst = [1,2,3,4]
#lst = [i*2**i for i in lst]
lst = [i << i for i in lst]
print(lst)

#(2)带有判断条件的推导式
lst = [1,2,3,4,5,6,7]
lst_new = []
for i in lst:
if i%2 ==0:
lst_new.append(i)
print(lst_new)

推导式改写

lst = [ i for i in lst if i%2==0]
print(lst)

(3)多循环推到式

lst1 = [“王振”,“黄俊”,“刘伟”]
lst2 = [“魏小林”,“刘思敏”,“陈芮”]
lst_new=[]
for i in lst1:
for j in lst2:
res = i+"?"+j
lst_new.append(res)
print(lst_new)

#推导式改写
lst = [i+"?"+j for i in lst1 for j in lst2]
print(lst)

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

lst_new = []
for i in lst1:
for j in lst2:
if lst1.index(i)==lst2.index(j):
res = i + “?” + j
lst_new.append(res)
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的列表推导式

dic = {‘x’: ‘A’, ‘y’: ‘B’, ‘z’: ‘C’ }
print("<______________>")
lst_new = []
for k,v in dic.items():
res = k+"="+v
lst_new.append(res)
print(lst_new)

lst = [k+"="+v for k,v in dic.items()]
print(lst)

(2).把列表中所有字符变成小写 [“ADDD”,“dddDD”,“DDaa”,“sss”]

常规

lst = [“ADDD”,“dddDD”,“DDaa”,“sss”]
lst_new=[]
for i in lst:
res = i.lower()
lst_new.append(res)
print(lst_new)

lst = [i.lower()for i in lst]
print(lst)

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

方法一

lst_new=[]
for x in range(0,6):
for y in range(0,6):
if x%20 and y%21:
res = (x,y)
lst_new.append(res)
print(lst_new)

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

方法二

lst_new = []
for x in range(6):
if x % 2 == 0:
for y in range(6):
if y % 2 == 1:
res = x,y
lst_new.append(res)
print(lst_new)

lst = [ (x,y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1 ]
print(lst)

print("<===>")
#(4).使用列表推导式 制作所有99乘法表中的运算
for i in range(1,10):
for j in range(1,10):
if i>=j:
print("{:d}{:d}={:2d}".format( i,j,ij ),end="")
print()

lst = [ "{:d}{:d}={:2d}".format(i,j,ij) for i in range(9,0,-1) for j in range(1,i+1) ]
print(lst)

(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]]

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

总结: 能控制下标等于控制了最后的结果

“”"

第一个效果

lst = [ M[i][j] * N[i][j] for i in range(3) for j in range(3) ]
print(lst)

第二个效果

[ [] , [] , [] ] 通过推导式遍历出三个新列表

lst = [ [] for i in range(3) ]
print(lst)

“”"
外层i动的慢的,里层的j动的快的,所以下标M[i][j]
在拿出i的时候, 里面的for 循环了三遍 是在一个新的列表当中实现的;
“”"

lst = [ [M[i][j] * N[i][j] for j in range(3)] for i in range(3) ]
print(lst)

### 集合推导式

“”"
案例:
满足年龄在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”:180,“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 = {三元运算符+for i in iterable}
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

“”"
enumerate(iterable,[start=0])
功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
参数:
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
start: 可以选择开始的索引号(默认从0开始索引)
返回值:迭代器
“”"

lst = [“吕洞宾”,“张果老”,“蓝采和”,“何仙姑”,“铁拐李”,“韩湘子”,“曹国舅”,“王文”]
it = enumerate(lst)

可以设置开始的索引值 start=5

it = enumerate(lst , start=5)
from collections import Iterable , Iterator
res = isinstance(it,Iterator)
for i in range(3):
res=next (it)
print(res)

list强转迭代器

print("<=======>")
res = list(it)
print(res)

1.通过推导式配合enumerate 实现

(5, ‘吕洞宾’)

dic = { k:v for k,v in enumerate(lst , start=1) }
print(dic)

2.通过dict 强转字典 实现

dic = dict(enumerate(lst , start=1))
print(dic)

(2)zip

“”"
zip(iterable, … …)
功能: 将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
返回: 迭代器

特点:不能匹对的多余值会被舍弃
“”"

zip 的基本使用

lst1 = [“黄俊”,“朱佳怡”,“王振”,“魏小林”]
lst2 = [“李博”,“刘伟”,“王瑛乾”]
lst3 = [“刘思敏”,“陈芮”]
it = zip(lst1,lst2)
print(list(it))

1.使用zip配合推导式实现

dic = {k:v for k,v in zip(lst1 , lst2 )}
print(dic)

2.通过dict 墙砖字典 实现

dic = dict(zip(lst1 , lst2 ))
print(dic)

### 生成器

“”"
#生成器本质是迭代器,允许自定义逻辑的迭代器

#迭代器和生成器区别:
迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑

#生成器可以用两种方式创建:
(1)生成器表达式 (里面是推导式,外面用圆括号)
(2)生成器函数 (用def定义,里面含有yield)
“”"
“”"
from collections import Iterator

(1) 生成器表达式 定义一个生成器

gen = (i*2 for i in range (1,5))
print(list(gen))
print(isinstance(gen,Iterator))

1.next 调用生成器

res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)
res = next(gen)
print(res)

res = next(gen)

print(res)

2. for 调用生成器

gen = (i* 2 for i in range(1,5))
for i in gen:
print(i)

3.for + next 调用生成器

gen = (i* 2 for i in range(1,5))
for i in range(2):
res = next(gen)
print(res)

4.用list强转,瞬间拿到所有数据

res = list(gen)
print(res)
“”"

### 生成器函数

“”"

yield 类似于 return

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

(1) 基本语法:

def mygen():
print(“第一次”)
yield 1
print(“第二次”)
yield 2
print(“第三次”)
yield 3

初始化生成器函数 , 返回生成器对象, 简称生成器

gen = mygen()
print(isinstance(gen,Iterator))

#第一次
res = next(gen)
print(res)

#第二次
res = next(gen)
print(res)

#第三次
res = next(gen)
print(res)

“”"

error

res = next(gen)
print(res)
“”"
“”"

代码解析:

第一次调用, print(“one”) yield 1 , 记录当前代码执行的状态15行, 把1直接返回,等待下一次调用
res = 1 print(1)
第二次调用, 从上一次代码的位置继续向下执行,print(“two”) yield 2 , 记录当前代码执行的状态18行 , 把2直接返回,等待下一次调用
res = 2 print(2)
第三次调用, 从上一次代码的位置继续向下执行,print(“three”) yield 3 , 记录当前代码执行的状态21行 , 把3直接返回,等待下一次调用
res = 3 print(3)

如果在进行第四次调用,因为没有yield 关键字返回数据, 所以直接报错 StopIteration
“”"

(2) 优化代码

def mygen():
for i in range(1,101):
yield"今天是杨浩第%s天吃粑粑"% (i)
gen = mygen()
for i in range(50):
res = next(gen)
print(res)
for i in range(50):
res = next(gen)
print(res)

(3) send 可以发送数据,发送给上一个yield

“”"

send

next和send区别:

next 只能取值
send 不但能取值,还能发送值

send注意点:

第一个 send 不能给 yield 传值 默认只能写None
最后一个yield 接受不到send的发送值

“”"

def mygen():
print(“start”)

res = yield 111
print(res)

res = yield 222
print(res)

res = yield 333
print(res)


print("end")

初始化生成器函数 -> 返回生成器对象 -> 简称生成器

gen = mygen()

第一次调用

第一次只能默认发送None,因为第一次没有上一个yield

val = gen.send(None)
print(val)

#第二次调用
val = gen.send(“abc”)
print(val)

第三次调用

val = gen.send(555)
print(val)

“”"
无论是next 还是 send 都可以调用生成器里面的数据
send 不但可以调用,还可以给yield 发送值

第一次调用send , 只能发送None ,因为还没有遇到yield
代码从上到下执行, print(“start”) 遇到 res = yield 111
记录当前代码执行的状态87行,把111值返回,等待下一次调用
外面的val = 111 print(111)

第二次调用send ,把444发送给上一次保存的位置87行

yield 进行接收 res = 444 87行往下执行 print(444) 遇到 res = yield 222
记录当前代码执行的状态90行,把222值返回,等待下一次调用
外面的val = 222 print(222)

第三次调用send ,把555发送给上一次保存的位置90行

yield 进行接收 res = 555 90行往下执行 print(555) 遇到 res = yield 333
记录当前代码执行的状态93行,把333值返回,等待下一次调用
外面的val = 333 print(333)

第四次调用send , 把555发送给上一次保存的位置93行

yield 进行接收 res = 666 93行往下执行 print(666) print(“end”)
没有任何yield 返回数据 , 出现StopIteration
到此程序彻底结束.
“”"

(4)yield from : 将一个可迭代对象变成一个迭代器返回

def mygen():
lst = [“魏小林”,“陈宁波”,“朱胜”]
yield from lst
gen = mygen()
print(next(gen))
print(next(gen))
print(next(gen))

案例: 用生成器来写一个斐波那契数列

“”"
生成器应用在大数据的场景中,按照需求依次取值,
切记不要直接迭代生成器所有数据
一旦数据量较大,类似于死循环
“”"

1 1 2 3 5 8 13 21 34 55 …

def mygen(maxlength):
a = 0
b = 1

i = 0
while i < maxlength:
	# print(b)
	yield b
	# 当前值 = 上上个值 + 上一个值
	a,b = b,a+b
	i+=1

gen = mygen(50)

按照需求量进行取值

for i in range(30):
print(next(gen))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值