一、列表推导式

'''通过一行循环判断,遍历一系列数据的方式'''
"""
推导式的语法:
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.推导式与生成器的更多相关文章

  1. python之三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    一 三元表达式.列表推导式.生成器表达式 一 三元表达式 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(r ...

  2. python基础17_列表推导式 vs 生成器表达式

    [ ] 列表推导式,是用简单的语法来生成列表, ( ) 生成器表达式,是用简单的语法创建个生成器. 外观上仅括号不一样. 虽然写起来方便,但是读起来稍显费力,另外,不易调试. # 列表推导式 prin ...

  3. python基础知识15---三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    阅读目录 一 三元表达式.列表推导式.生成器表达式 二 递归与二分法 三 匿名函数 四 内置函数 五 阶段性练习 一. 三元表达式.列表推导式.生成器表达式 1 三元表达式 name=input('姓 ...

  4. Python_列表推导式_生成器的表达式_各种推导式_40

    列表推导式: #列表推导式: egg_list = [] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list) egon egg_ ...

  5. Python_迭代器、生成器、列表推导式,生成器表达式

    1.迭代器 (1)可迭代对象 s1 = ' for i in s1: print(i) 可迭代对象 示例结果: D:\Python36\python.exe "E:/Python/课堂视频/ ...

  6. Python之推导式、生成器表达式

    l = [i for i in range(10)] print(l) l1 = ['选项%s'%i for i in range(10)] print(l1) 1.把列表解析的[]换成()得到的就是 ...

  7. python全栈开发 生成器 :生成器函数,推导式及生成器表达式

    python 全栈开发 1.生成器函数 2.推导式 3.生成器表达式 一.生成器函数 1.生成器: 生成器的本质就是迭代器 (1)生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), ...

  8. python 三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    http://www.cnblogs.com/linhaifeng/articles/7580830.html 三元表达式.列表推导式.生成器表达式.递归.匿名函数.内置函数

  9. python 三元表达式、列表推导式、生成器表达式

    一 三元表达式.列表推导式.生成器表达式 一 三元表达式 name=input('姓名>>: ') res='mm' if name == 'hahah' else 'NB' print( ...

随机推荐

  1. Python-自动用0补取长度

    描述 Python zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0. 语法 zfill()方法语法: str.zfill(width) 参数 width -- 指定字符串的长度. ...

  2. 线下---复习day04---作业

    1 学的不好的同学:用ajax提交一个json格式数据,返回一个json格式数据,console.log打印出来 2 通过ajax上传一个文件并保存起来,前端接收到,弹窗说上传成功 urls.py f ...

  3. dva的简介

    dva的定义 dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装; redux 他是react当中的仓库,如果熟悉vue的话,他的功能 ...

  4. day54 js基础

    目录 一.变量 二.数据类型 1 数值类型(number) 2 字符类型(string) 3 字符类型常用方法 4 布尔值(boolean) 5 null与undefined 6 对象 7 运算符 8 ...

  5. 【GIT】git详解

    目录 一.基础使用 二.分支管理 三.提交树操作 四.复杂工作流处理 ----------------------------------------------------------------- ...

  6. 06 flask源码剖析之路由加载

    06 Flask源码之:路由加载 目录 06 Flask源码之:路由加载 1.示例代码 2.路由加载源码分析 1.示例代码 from flask import Flask app = Flask(__ ...

  7. 机器学习实战基础(二十七):sklearn中的降维算法PCA和SVD(八)PCA对手写数字数据集的降维

    PCA对手写数字数据集的降维 1. 导入需要的模块和库 from sklearn.decomposition import PCA from sklearn.ensemble import Rando ...

  8. Unity-Editor

    Undo.RecordObject [MenuItem("Example/Random Rotate")] static void RandomRotate() { var tra ...

  9. 【JVM之内存与垃圾回收篇】堆

    堆 堆的核心概念 堆针对一个 JVM 进程来说是唯一的,也就是一个进程只有一个 JVM,但是进程包含多个线程,他们是共享同一堆空间的. 一个 JVM 实例只存在一个堆内存,堆也是 Java 内存管理的 ...

  10. Win10系统报错问题集锦

    收集记录win10的坑 错误1 应用程序-特定 权限设置并未向在应用程序容器 不可用 SID (不可用)中运行的地址 LocalHost (使用 LRPC) 中的用户 NT AUTHORITY\SYS ...