推导式与生成器
一.推导式
概念: 通过一行循环判断,遍历出一系列数据的方法叫做推导式
语法: val for val in Iterable (把想要的值放在for前边)
特点: 简洁,高效
种类: 根据套在推导式外层的符号来判断是什么类型的推导式
列表推导式:[val for val in Iterable]
集合推导式:{val for val in Iterable}
字典推导式:{a:b for a,b in Iterable}
1.列表推导式:[val for val in Iterable]
# 1.单循环推导式
lst=[i for i in range(5)]
print(lst)
# 2.带判断条件的单循环推导式
"""注意:for循环后面只能跟单行分支"""
# 输出10以内被3整除的数
lst=[i for i in range(11) if i%3==0]
print(lst)
# 3.多条件,输出10以内奇数乘3,偶数乘5(判断在前,循环在后)
lst = [i*5 if i%2==0 else i*3 for i in range(11)]
print(lst)
# 4.带判断条件多循环推导式
lst1=["aa","bb","cc"]
lst2=["11","22","33"]
# 一一对应
lst=[i+j for i in lst1 for j in lst2 if lst1.index(i)==lst2.index(j)]
print(lst)
2.集合推导式{val for val in Iterable}
和列表推导式用法一样,集合自动去重
3,字典推导式:{k:v for k,v in Iterable}
# 1.enumerate(Iterable,start=0)
"""
功能: 将索引号和Iterable中的值,一个一个拿出来配对组成元组
参数:
Iterable:可迭代型数据(容器类型数据,range对象,迭代器)
start :设置开始索引号,默认从0开始
返回值: 迭代器
"""
strvar="abcde"
it=enumerate(strvar) #默认索引从0开始
it=enumerate(strvar,start=1)#索引从1开始
for a,b in it:
print(a,b)
# 推导式
dic={k:v for k,v in enumerate(strvar)}
print(dic) # {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
# dict强转
dic=dict(enumerate(strvar))
print(dic) # {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
# 2.zip(Iterable,....)
"""
功能: 将多个Iterable中的值,一个一个拿出来配对成元组
参数: Iterable 可迭代型数据(容器类型数据,range对象,迭代器)
返回值: 迭代器
原则: zip的配对原则是按照相同的索引组成元组,如果没有相同索引,自动舍弃
"""
strvar="abc"
lst=[11,22,33,44]
# 字典推导式
dic={k:v for k,v in zip(strvar,lst)}
print(dic) # {'a': 11, 'b': 22, 'c': 33}
# 通过dict强转
dic=dict(zip(strvar,lst))
print(dic) # # {'a': 11, 'b': 22, 'c': 33}
二.生成器(generator)
1.生成器概念
"""
概念: 生成器本质是迭代器,是允许自定义逻辑的迭代器
生成器与迭代器区别:
迭代器是系统内置的,重写不了迭代逻辑
生成器是用户自定义的,可以重写迭代逻辑
生成器的创建:
1.生成器表达式: 元组推导式 (里面是推导式,外面是圆括号)
2.生成器函数 :用def定义,里面含有yield的函数
"""
# 1.生成器表达式:
gen=(i for i in range(6))
# 2.生成器函数
2.生成器表达式
gen=(i for i in range(6))
print(next(gen))
3.生成器函数
# 生成器函数
"""
yield 类似于return
共同点: 执行到这句话时都会把值返回去,没有返回值默认返回None
不同点:
yield每次返回时,都会记住上一次离开时执行的位置
return会直接终止函数,每次从头调用
"""
# 1.生成器函数
def func():
for i in range(10):
yield i
gen=func() #初始化生成器函数
print(next(gen)) #调用生成器函数
print(next(gen))
for i in range(3):
print(next(gen))
# 2.send 语法使用
"""
格式: 生成器.send(发送的值)
send: 发送的值是传给上一个yield的
next和send区别:
next 只能获取返回的值
send 不但能获取值,还可以向函数内发送值
注意点:
第一个send不能给yield传值,默认只能写None
最后一个yield接受不到send发送的值
"""
def func():
res = yield 1
print(res,'aaa')
res = yield 2
print(res,'bbb')
res = yield 3
print(res,'ccc')
gen=func() #初始化生成器函数
res=gen.send(None) # 第一次发送数据,无脑None -- 没有打印数据
print(res) # 1
res=gen.send(11) # 第二次可以发送数据 -- 打印 11 aaa
print(res) # 2
res = gen.send(22) # 22 bbb
print(res) # 3
# 3.yield from : 将一个可迭代对象变成一个迭代器返回
def func():
yield from "abcde" #把字符串变成了迭代器
gen=func() #初始化生成器函数
print(next(gen)) #a
print(next(gen)) #b