推导式
通过一行循环判断遍历出一些列数据的方法叫做推导式
推导式comprehensions(又称解析式),是Python的一种独有特性。
推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:
化简代码用的
推导式的核心为 for 循环。根据返回对象的不同,推导式可区分为列表推导式,字典推导式,集合推导式等。不同推导式在语法上基本一致。
实际上就是根据公式生成新的,想要的列表,集合,字典
语法:
val for val in iterable [if 条件表达式]
其中 if 条件判断根据需要,可有可无。
1.推导式基本语法
#老方法 lst = [] for i in range(1,51): lst.append(i) print(lst) #改写推导式 lst = [ i for i in range(1,51) ] print(lst)
2.列表推导式
for前面是要获取的存在列表里面的数据
list1 = [i for i in range(1, 10) if i % 2 == 0] print(list1) [2, 4, 6, 8] list2 = [i for i in range(0, 10, 2)] print(list2) [0, 2, 4, 6, 8]
#小练习
#1.[1,2,3,4,5] => [2,4,6,8,10] lst = [ i*2 for i in range(1,6) ] print(lst)
2.带有判断条件的推导式
“”“注意点:for后面紧跟的判断条件只能是单项分支.”“”
“”“[1,2,3,4,5,6,7,8,9,10] => [1,3,5,7,9 … ]”“”
lst = [1,2,3,4,5,6,7,8,9,10] 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.多循环推导式
lst1 = ["孙杰龙","陈露","曹静怡"] lst2 = ["王志国","邓鹏","合理"] lst_new = [] for i in lst1: for j in lst2: lst_new.append(i+"♡♢♤♠"+j) print(lst_new) #改写推导式 lst = [ i+"♡♢♤♠"+j for i in lst1 for j in lst2 ] print(lst)
创建多个for循环的实现列表推导式: 等同于for循环嵌套
#创建列表:[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
list1 = [(i, j) for i in range(1, 3) for j in range(3)] print(list1) [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
合并列表为字典:
list1 = ['name', 'age', 'gender'] list2 = ['Tom', 18, 'man'] d1 = {list1[i]: list2[i] for i in range(len(list2))} print(d1) {'name': 'Tom', 'age': 18, 'gender': 'man'}
如果两个列表数据不同,按个数少的长度来统计,即len(最少数据的列表)
4.带有判断条件的多循环推导式
lst_new = [] for i in lst1: for j in lst2: if lst1.index(i) == lst2.index(j): lst_new.append(i+"♡♢♤♠"+j) print(lst_new) #改写推导式 lst = [i+"♡♢♤♠"+j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)] print(lst)
5.求M,N中矩阵和元素的乘积
# =>实现效果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 = [ [1,2,3] ,[4,5,6] , [7,8,9] ] N = [ [2,2,2] ,[3,3,3] , [4,4,4] ] lst = [[M[i][j] * N[i][j] for j in range(3)] for i in range(3)] print(lst)
列表推导式练习
6.集合推导式
案例:
满足年龄在18到21,存款大于等于5000 小于等于5500的人,
开卡格式为:尊贵VIP卡老x(姓氏),否则开卡格式为:抠脚大汉卡老x(姓氏)
把开卡的种类统计出来
lst = [ {"name":"赵沈阳","age":18,"money":3000}, {"name":"赵万里","age":19,"money":5200}, {"name":"赵蜂拥","age":20,"money":100000}, {"name":"赵世超","age":21,"money":1000}, {"name":"王志国","age":18,"money":5500}, {"name":"王永飞","age":99,"money":5500} ] setvar = set() for i in lst: print(i) # {'name': '赵沈阳', 'age': 18, 'money': 3000} if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500: res = "尊贵VIP卡老{}".format(i["name"][0]) else: res = "抠脚大汉卡老{}".format(i["name"][0]) # 添加到集合中 setvar.add(res) print(setvar) #{ 三元运算符 + 推导式 } setvar = { "尊贵VIP卡老{}".format(i["name"][0]) if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500 else "抠脚大汉卡老{}".format(i["name"][0]) for i in lst } print(setvar)
7.字典推导式
一.enumerate
enumerate(iterable,[start=0])
功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组,通过迭代器返回
参数:
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
start: 可以选择开始的索引号(默认从0开始索引)
返回值:迭代器
#基本语法
from collections import Iterator,Iterable lst =["王文","吕洞宾","何仙姑","铁拐李","张国老","曹国舅","蓝采和","韩湘子"] it = enumerate(lst) it = enumerate(lst,start=100) print(isinstance(it,Iterator)) #next print( next(it) ) # for + next (推荐,数据较大时使用。海量数据时不能一次性把数据都放到内存中) for i in range(3): print(next(it))
# for for i in it: print(i)
#dict 强转迭代器,这是一次性把数据全部转换成dict,数据较大时容易死机
print(dict(it))
#(1) 字典推导式 配合 enumerate 来实现
dic = {k:v for k,v in enumerate(lst,start=100)} print(dic) (100, '王文') (101, '吕洞宾') (102, '何仙姑') (103, '铁拐李') (104, '张国老') (105, '曹国舅') (106, '蓝采和') (107, '韩湘子')
#(2) 使用dict强转迭代器,瞬间得到字典
dic = dict( enumerate(lst,start=100) ) print(dic)
二.zip
特点:按照索引配对
zip(iterable, … …)
功能: 将多个iterable中的值,一个一个拿出来配对组成元组,通过迭代器返回 要是生成字典只能有两个iterable
iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
返回: 迭代器
# 基本语法 # lst1 = ["孙开启","王永飞","于朝志"] # lst2 = ["薛宇健","韩瑞晓","上朝气"] # lst3 = ["刘文博","历史园","张光旭"] # 在索引下标同时存在时,才会进行配对,否则舍弃. lst1 = ["孙开启","王永飞","于朝志"] lst2 = ["薛宇健","韩瑞晓"] lst3 = ["刘文博"] it = zip(lst1,lst2,lst3) print(list(it))
两个容器才能用字典方法强转,否则报错
#(1) 字典推导式 配合 zip 来实现
lst_key = ["ww","axd","yyt"] lst_val = ["王维","安晓东","杨元涛"] #('ww', '王维'), ('axd', '安晓东'), ('yyt', '杨元涛') dic = {k:v for k,v in zip(lst_key , lst_val) } print(dic)
以最短可迭代数据为准,多的舍弃
#(2) 使用dict强转迭代器,瞬间得到字典
dic = dict( zip(lst_key , lst_val) ) print(dic)
生成器
理解生成器,最好的方法就是给他取个突出其本质的别名:生成数据的机器代码。
生成器是一种用时间换空间的做法。比如,利用list列表储存全体正整数,无穷个正整数再大的内存也无法装得下,这个时候就可以使用生成器,实现用一段代码来储存全部正整数的作用
一,生成器的官方定义
在Python中,一边循环一边计算的机制,称为生成器:generator。
(1).生成器表达式
生成器表达式返回一个生成器对象即generator object,需要用一个变量名来接收并绑定。
(2).生成器函数
含有 yield 关键字的函数,调用该函数时会返回一个生成器。
二,next()&next()和send()方法
1,__next__()&next()的区别 __next__()是生成器对象的实例方法,next()是python的内置方法。他们实现的功能是一样的,只能对可迭代的对象使用。 2,next()和send()用以唤醒生成器 当生成器函数中执行yield时,程序会卡在yield的地方不执行,next()和send()的作用就是唤醒卡住的程序,让他继续执行。 3,send()方法的作用 send()作为生成器对象的实例方法,可以向生成器发送数据并唤醒生成器函数。一般send()方法要写在next()方法后面,当next()和send()写在一块时,相当于唤醒两次生成器。 生成器表达式无法像列表推导式那样直接输出,它和可迭代对象一样只能采用for循环调用next()函数,原因在于range返回的是一个可迭代对象, 列表推导式之所以能直接print就是因为 []将可迭代对象转为列表。
#生成器
#生成器本质是迭代器,允许自定义逻辑的迭代器
#迭代器和生成器区别:
迭代器本身是系统内置的.重写不了.
而生成器是用户自定义的,可以重写迭代逻辑
#生成器可以用两种方式创建:
(1)生成器表达式 (里面是推导式,外面用圆括号)
(2)生成器函数 (用def定义,里面含有yield)
三, 生成器表达式 (里面是推导式,外面用圆括号)
gen = ( i for i in range(10) ) print(gen)
#判断类型
from collections import Iterator,Iterable print(isinstance(gen,Iterator))
四, 生成器的调用
1.next 调用生成器
print(next(gen)) print(next(gen))
2.for + next 调用生成器
for i in range(3): print(next(gen))
3.for 调用生成器所有数据
for i in gen: print(i)
4.list强转生成器,瞬间得到所有数据
gen = ( i for i in range(10) ) print(list(gen)) #print(next(gen)) error # StopIteration 超出范围
python中的推导式、生成器(二):https://developer.aliyun.com/article/1495752