迭代器协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代(只能往后走,不能往前退)
可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个_iter_()方法)
协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象
for循环本质:循环所有对象,全都是使用迭代器协议.
lt = ['l', 'i', 'u']
# 下标访问方式
lt[0]
lt[1]
lt[2]
# lt[3] # 超出边界报错
# 遵循迭代器协议访问方式
iter_test = lt.__iter__()
iter_test.__next__()
iter_test.__next__()
iter_test.__next__()
# iter_test.__next__()# 超出边界报错
# for 循环访问方式
# for 循环的本质就是遵循迭代器协议的方式,先调用iter_test = lt.__iter__()
# 再调用iter_test.__next__(),直到for循环捕捉到StopIteration终止循环
# for 循环所有对象的本质都是一样的道理
for i in lt:
print(i)
# while模仿for循环
iter_test = lt.__iter__()
while True:
try:
print(iter_test.__next__())
except StopIteration:
print("迭代完毕,循环终止了...")
break
生成器初步探索
生成器:可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__()方法).所以生成器就是可迭代对象.
生成器分类及在python中的表现形式:1.生成器函数:常规函数定义,但是使用yield而不是return返回结果.yield一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行.
2. 生成器表达式:类似于列表推导,但是生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表.
python使用生长器对延迟操作提供了支持.所谓延迟操作,是指在需要的时候产生结果,而不是立刻产生结果.这也是生成器的主要好处.
name="刘备"
# 三元表达式
res = "厉害了" if name=="刘备" else "不行"
列表解析:
语法:
[expression for iter_val in iterable]
[expression for iter_val in iterable if cond_expr]
lt = [i+2 for i in range(10) ]
lt = [i+2 for i in range(10) if i>6]
生成器:
1.来自函数(生成器函数,可以保存函数的运行状态)
def gene():
yield 6
yield 7
yield 8
v = gene()
print(v.__next__())
# 可以在之间加上代码
代码
print(v.__next__())
2. 来自列表解析
v = (i for i in range(10))
print(v.__next__()) # 生成器本身就有 __next__()
生成器特性:
1. 语法上和函数类似. 只是生成器函数使用yield返回一个值
2. 自动实现迭代器协议,可以直接__next__()
3. 状态挂起:生成器使用yield语句返回一个值.
生成器优点: 1.延迟计算,一次返回一个结果.并不会一次产生全部结果,这样不仅节省内存,而且这种机制非常适合处理大数据.
三国人物.txt文件内容
{"name":"刘备", "age":"25"}
{"name":"关羽", "age":"24"}
{"name":"张飞", "age":"23"}
{"name":"曹操", "age":"24"}
{"name":"郭嘉", "age":"23"}
{"name":"曹丕", "age":"5"}
def getPeople():
with open("三国人物", "r", encoding="utf-8") as f:
for i in f:
yield i
gene = getPeople()
# for g in gene:
# print(eval(g)["age"])
# 使用三元表达式求和
res = sum(int(eval(g)["age"]) for g in gene)
print(res)