迭代器总结(迭代取值和索引取值的对比)
迭代器主要就是一个迭代取值,另外一种取值方式就是索引(下标)取值
l = [1, 2, 3, 4]
res = l.__iter__()
res.__next__() # 1
res.__next__() # 2
迭代取值,不依赖于索引取值,不能够重复取值,只能从左到右固定取值
索引取值,能够重复取值,他需要容器类型
生成器(自定义的迭代器)(yield)
若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象.
生成器其实就是一个自定义的迭代器
def index():
print('index')
yield 123
print('index1')
yield
res=index()#res.__iter__()
print(res.__next__())#123
#range()这个内置函数有三种用法
#range(10) range(0,10) range(0,10,2)
# 利用生成器的原理实现range函数的功能
def my_range(start,stop=None,step=1):
if not stop:#stop如果没有值传入,即if True:
stop=start
start=0
while start < stop:
yield start
start+=step
for i in my_range(10):
print(i)
生成器yield的其他用法:
def eater(name):
print('%s正在吃...'%name)
while True:
food = yield
print('%s正在吃%s'%(name,food))
res=eater('kk')
res.__next__()
res.send('便便')#send做了两件事,一件是传值给yield,一件是执行__next__()
生成器表达式
创建一个生成器对象有两种方式,一种是调用带yield的函数,另一种就是生成器表达式
#列表生成式
res=[name for name in name_list]
print(res)# 就是一个列表
与列表生成式的语法格式相同,只需要将[]换成()就可以。
res1=(name for name in name_List)
print(res1) # <generator object <genexpr> at 0x00000218F4569CF0>
print(res1.__next__())
生成式表达式如果不使用数据,就不给你数据。把生成器、迭代器看成一个工厂,什么时候需要就会给你数据,工厂就会给你加工数据,目的就是为了节省内存空间。
生成器笔试题
# 求和
def add(n, i):
return n + i
# 调用之前是函数 调用之后是生成器
def test():
for i in range(4):
yield i
g = test() # 初始化生成器对象
for n in [1, 10]:
g = (add(n, i) for i in g)
res = list(g)
print(res)
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
C. res=[20,21,22,23]
#D. res=[21,22,23,24]
yield和return的对比
yield遇到代码不会停止,而是停住,可以有多个返回值,以元组的形式返回,yield会把函数变成生成器,__next__()取值
代码遇到return会停止,有返回值并且还支持多个,以元组的形式返回