一、列表推导式

'''通过一行循环判断,遍历一系列数据的方式'''
"""
推导式的语法:
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

最新文章

  1. JavaScript如何获取网页url中的参数
  2. Windows10系统如何更改程序的默认安装目录?
  3. 关于struts和Spring 结合到一起之后存在ACtion创建单实例还是多
  4. Struts2中获取servlet API的几种方式
  5. 导航栏视图设置 tabbleView 是设置总背景图
  6. 如何让Eclipse的智能提示像VS一样霸气
  7. Java 加密 AES 对称加密算法
  8. Android 程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短信
  9. 【Flash ANE iOS】关于Flash ANE在iOS上面遇到的一些问题
  10. BootStrap详解之(二)
  11. Struts加入拦截器后取不到页面参数
  12. Java中多线程同步类 CountDownLatch
  13. 【java提高】---数组增删 list删除 map删除
  14. windows 7 netsh wlan命令连接wifi
  15. KERBEROS PROTOCOL TUTORIAL
  16. mysql 查询时指定校对规则
  17. (后端)解决code唯一码(java)简便方法
  18. python设计模式之单例模式(转)
  19. 【CF429E】Points and Segments(欧拉回路)
  20. YOCVM

热门文章

  1. centos7-修改默认python为3
  2. PowerJob 的故事开始:“玩够了,才有精力写开源啊!”
  3. Let&#39;s GO(三)
  4. 数据可视化之分析篇(十)Power BI应用:如何计算在职员工数量?
  5. 那些非cmake生成的VTK工程存在的让人崩溃的坑
  6. 定时器之Timer
  7. Postman接口测试实战分享,这5个问题你必须得知道!【软件测试工程师经验分享】
  8. 为Dark模拟做出的一些微小的贡献
  9. 第一讲 Windows10系统下IDE-CLion的安装与配置
  10. 数字图像处理 第四章 P157 小错误