可迭代对象
1.迭代就是更新换代,每次迭代都必须基于上一次的迭代成果,单纯的重复不是迭代
2.代码展示
while True:
print('嘿嘿嘿')
n = 0
while n < 10:
print(n)
n += 1
3.如和判断可迭代对象
3.1.'内置__iter__方法的都可以叫可迭代对象'读作:双下iter方法
3.2.int float bool 以及函数名都不是可迭代对象
3.3.字符串,列表,字典,元组,集合,文件都是可迭代对象,其中文件还是迭代器对象
迭代器对象
1.作用
迭代器对象为我们提供了一种不依赖索引的取值方式,因此我们可以对字典、集合这种无序类型循环取值。
2.如何判断迭代器对象
内置有__iter__和__next__方法的成为迭代器对象
3.可迭代对象与迭代器对象的关系
可迭代对象调用__iter__方法之后就会变成迭代器对象
迭代器对象调用__iter__方法无论多少次还是迭代器对象本身
4.迭代器对象迭代取值
s1 = 'abc'
s1 = s1.__iter__()
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
print(s1.__next__())
l1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = l1.__iter__()
count = 0
while count < len(l1):
print(res.__next__())
count += 1
6.迭代器反复使用
l1 = [1,2,3,4]
print(l1.__iter__().__next__())
print(l1.__iter__().__next__())
print(l1.__iter__().__next__())
l1 = l1.__iter__()
print(l1.__iter__().__next__())
print(l1.__iter__().__next__())
print(l1.__iter__().__next__())
7.简写
res = l1.__iter__() ===> iter(l1)
res.__next__() ===> next(res)
8.补充说明
可迭代对象和迭代器对象无法通过打印看到其内部信息
这时候他们都能够帮你节省内存,相当于是一个临时工厂,你要一个数据就给一个。
迭代取值与索引取值的差异
l1 = [1,2,3,4,5]
print(l1[0])
print(l1[1])
print(l1[2])
print(l1[4])
'优势:可以随意反复地获取任意数据值(自由)'
'劣势:针对无序的容器类型无法取值(类型限制)'
res = l1.__iter__()
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
'优势:可以对无序的容器类型取值(通用)'
'劣势:取值只能一直向前,不能回退(不可逆)'
for循环的本质
语法结构
for 变量名 in 可迭代对象:
for循环体代码
1.for会自动将in后面的数据调用__iter__()变成迭代器对象
2.之后每次循环调用__next__()取值
3.最后没有值__next__()会报错 for能够自动处理该错误 让循环正常结束
生成器对象
1.本质就是迭代器对象(内置__iter__ 和 __next__方法),只不过迭代器是python解释器提供给我们的(现成的),生成器是我们自己定义的。
2.生成器的主要作用是节省代码
一种不依赖索引的取值方式
可以节省数据类型占用的内存空间(主要)
3.生成器对象代码实现
def index():
print('我是谁呀 嘿嘿嘿~')
yield 111, 222, 333
print('你追我 如果你追到我 我就... 嘿嘿嘿~')
yield 222
print('实在跑不动了 嘿嘿嘿~')
yield 333
"""
当函数体代码中有yield关键字
函数名第一次加括号调用不会执行函数体代码
而是由普通的函数变成了迭代器对象(生成器)
"""
print(index)
res = index()
print(res)
res.__next__()
res.__next__()
"""
yield可以在函数体代码中出现多次
每次调用__next__方法都会从上到下执行,知道遇到yield停留到此处
"""
print(res.__next__())
yield后面如果有数据值,则会像return一样返回出去,如果有多个数据值,则会自动组织成元组返回。
4.生成器对象练习
def my_range(start_num, end_num):
while start_num < end_num:
yield start_num
start_num += 1
for i in my_range(1, 10):
print(i)
def my_range(start_num, end_num = None):
if not end_num:
end_num = start_num
start_num = 1
while start_num < end_num:
yield start_num
start_num += 1
for i in my_range(10):
print(i)
def my_range(start_num, end_num = None, step = 1):
if not end_num:
end_num = start_num
start_num = 1
while start_num < end_num:
yield start_num
start_num += step
for i in my_range(1,10,2):
print(i)
yield其他用法
yield不仅能返回值,还可以接收外界传来的值
def index(name,food=None):
print(f'{name}准备干午饭!!!')
while True:
food = yield
print(f'{name}正在吃{food}')
res = index('jason')
res.__next__()
res.send('生蚝')
生成器表达式
即:"元组生成式"
l1 = (i**2 for i in range(10) if i > 3)
print(l1)