15,Python3 迭代器与生成器
15-1 迭代器
15-1-1 基础知识
1,迭代器:迭代取值的工具,迭代是重复的过程,每一次重复都是基于上次的结果而继续的,单纯的重复不是迭代
# 可迭代对象: 但凡内置有__iter__()方法的都称之为可迭代对象
# 字符串---列表---元祖---字典---集合---文件操作 都是可迭代对象
# 调用可迭代对象下的__iter__方法将其转换为可迭代对象
d = {
'a':1, 'b':2, 'c':3}
d_iter = d.__iter__() # 把字典d转换成了可迭代对象
# d_iter.__next__() # 通过__next__()方法可以取值
print(d_iter.__next__()) # a
print(d_iter.__next__()) # b
print(d_iter.__next__()) # c
# 没值了以后就会报错, 抛出异常StopIteration
#-----------------------------------------------
d = {
'a':1, 'b':2, 'c':3}
d_iter = d.__iter__()
while True:
try:
print(d_iter.__next__())
except StopIteration:
break
# 对同一个迭代器对象,取值取干净的情况下第二次取值的时候去不了,没值,只能造新的迭代器
15-1-2 迭代器与for循环工作原理
#可迭代对象与迭代器详解
#可迭代对象:内置有__iter__() 方法对象
# 可迭代对象.__iter__(): 得到可迭代对象
#迭代器对象:内置有__next__() 方法
# 迭代器对象.__next__():得到迭代器的下一个值
# 迭代器对象.__iter__(): 得到的值迭代器对象的本身(调跟没调一个样)-----------> 为了保证for循环的工作
# for循环工作原理
d = {
'a':1, 'b':2, 'c':3}
d_iter = d.__iter__()
# 1,d.__iter__() 方法得到一个跌倒器对象
# 2,迭代器对象的__next__()方法拿到返回值,将该返回值赋值给k
# 3,循环往复步骤2,直到抛出异常,for循环会捕捉异常并结束循坏
for k in d:
print(k)
# 可迭代器对象不一定是迭代器对象------------迭代器对象一定是可迭代对象
# 字符串---列表---元祖---字典---集合只是可迭代对象,不是迭代器对象、
# 文件操作时迭代器对象也是可迭代对象
15-2 生成器(本质就是迭代器)
# 函数里包含yield,并且调用函数以后就能得到一个可迭代对象
def test():
print('第一次')
yield 1
print('第二次')
yield 2
print('第三次')
yield 3
print('第四次')
g = test()
print(g) # <generator object test at 0x0000014C809A27A0>
g_iter = g.__iter__()
res1 = g_iter.__next__() # 第一次
print(res1) # 1
res2 = g_iter.__next__() # 第二次
print(res2) # 2
res3 = g_iter.__next__() # 第三次
print(res3) # 3
# 补充
len(s) -------> s.__len__()
next(s) ------> s.__next__()
iter(d) -------> d.__iter__()
15-2-1 yield 表达式
def person(name):
print("%s吃东西啦!!"%name)
while True:
x = yield None
print('%s吃东西啦---%s'%(name,x))
g = person('aini')
# next(g) =============== g.send(None)
next(g)
next(g)
# send()方法可以给yield传值
# 不能在第一次运行时用g.send()来传值,需要用g.send(None)或者next(g) 来初始化,第二次开始可以用g.send("值")来传值
g.send("雪糕") # aini吃东西啦---雪糕
g.send("西瓜") # aini吃东西啦---西瓜
15-2-2 三元表达式
x = 10
y = 20
res = x if x > y else y
# 格式
条件成立时返回的值 if 条件 else 条件不成立时返回的值
15-2-3 列表生成式
l = ['aini_aaa','dilnur_aaa','donghua_aaa','egon']
res = [name for name in l if name.endswith('aaa')]
print(res)
# 语法: [结果 for 元素 in 可迭代对象 if 条件]
l = ['aini_aaa','dilnur_aaa','donghua_aaa','egon']
l = [name.upper() for name in l]
print(l)
l = ['aini_aaa','dilnur_aaa','donghua_aaa','egon']
l = [name.replace('_aaa','') for name in l if name.endswith('_aaa')]
print(l)
15-2-4 其他生成器(——没有元祖生成式——)
### 字典生成器
keys = ['name','age','gender']
res = {
key: None for key in keys}
print(res) # {'name': None, 'age': None, 'gender': None}
items = [('name','aini'),('age',22),('gender','man')]
res = {
k:v for k,v in items}
print(res)
## 集合生成器
keys = ['name','age','gender']
set1 = {
key for key in keys}
## 没有元祖生成器
g = (i for i in range(10) if i % 4 == 0 ) ## 得到的是一个迭代器
#### 统计文件字符个数
with open('aini.txt', mode='rt', encoding= 'utf-8') as f:
res = sum(len(line) for line in f)
print(res)
15-2-5 二分法
l = [-10,-6,-3,0,1,10,56,134,222,234,532,642,743,852,1431]
def search_num(num,list):
mid_index = len(list) // 2
if len(list) == 0:
print("没找到")
return False
if num > list[mid_index]:
list