48.python之迭代器和生成器

迭代器

  • 迭代器是一个可以记住访问遍历的位置的对象,从集合的第一个元素开始访问,直到集合中所有元素被访问完毕
  • 迭代器器只能从前往后一个一个遍历,不能后退
  • 一般的数据都是一次性写入到内存中,而迭代器是按需加载,有一点内容就写入内存中,此时可以立即使用内存中的数据进行逻辑处理,这样就不需要等待所有的数据都写入内存中后才进行逻辑处理,提高了使用的效率
  • 若是数据中内容很大时,相比较一次性将数据写入内存中,迭代器使用一个数据就放入内存中的的方式更加高效

总结:迭代器是能够被next()函数调用,并不断返回下一个值的对象(Iterator)

迭代器使用

1)生成一个迭代器对象

用法:把可迭代对象转为一个迭代器对象

iter(iterable)

参数:

  • iterable:可迭代的数据类型,包含字符串、列表、元组、字典、集合等
  • 能使用for进行循环遍历的是可迭代的对象

2)使用迭代器对象

1.返回一个迭代器中数据

next(iterator)

2.直接取出迭代器中所有的数据

list(iterator)

3.使用for循环返回迭代器中数据

for i in iterator:
    print(i)

参数:

  • iterator:迭代器对象
  • 迭代器对象取值,取一个少一个,若是迭代器中成员全部都遍历完,再使用next会报错:StopIteration

例1:使用next返回迭代器中数据

result = iter([1, 2, 3])
print(next(result))
print(next(result))
print(next(result))
print(next(result))

结果:
在这里插入图片描述

例2:使用for循环返回迭代器中数据,不会报错

# 创建一个迭代器
result = iter([1, 2, 3])

for i in result:
    print(i)

print('---------')

for i in result:
    print(i)

结果:

  • 使用for循环返回迭代器中数据,不会出现报错情况
  • 当完整的读取一次迭代器器中的数据后,发现后面再使用for循环不会返回迭代器中数据,因为迭代器每次都会把数据放入内存中,当放在内存中被读取后,内存就会被释放,所以使用一次for循环读取完迭代器中数据后,这个迭代器中的数据就空了,因此不会再返回数据
  • 所以上面使用next会报错也是因为迭代器中此时已经没有数据了
    在这里插入图片描述

例3:使用list返回迭代器器中所有的数据

# 创建一个迭代器
result = iter((1, 2, 3))

# 返回迭代器中所有的数据
print(list(result))

在这里插入图片描述

判断是否是迭代器和迭代对象:

from collections.abc import Iterable,Iterator

t = (1, 2, 3)
# 创建一个迭代器
result = iter(t)

# isinstance判断变量是否是某个数据类型
# Iterator表示迭代器,Iterable表示可迭代对象
# 判断t是否是迭代器
t1 = isinstance(t, Iterator)
# 判断t是否是可迭代对象
t2 = isinstance(t, Iterable)


r1 = isinstance(result, Iterator)
r2 = isinstance(result, Iterable)

print(t1, t2)
print(r1, r2)

根据运行结果可以看出:

  • 元组是一个可迭代对象,但不是迭代器
  • 迭代器同时也是一个可迭代对象

生成器

  • 生成器是一种特殊的迭代器,可以自定义也可以使用元组推导式去定义
  • 生成器是按照某种算法去推算下一个数据或结果,只需要往内存中存储一个生成器,节约内存消耗,提升性能
  • 含有yield关键字的函数(生成器函数),返回的结果是一个迭代器,换句话说,生成器函数就是一个返回迭代器的函数

方式1:for循环生成法–yield

  • 使用for循环,循环中每个成员调用yield函数,也就是将for循环中每个成员放入迭代器中
  • 只有调用迭代器的时候,for循环中的成员才会被放入,也就是每使用一次next(iterator),就将for循环中一个成员放入迭代器中
def test():
    for i in range(10):
        yield i

result = test()

# 只有在调用迭代器的时候,for循环中的成员才会被放入迭代器中
# 也就是按需加载
print(next(result))

print(next(result))

结果:
在这里插入图片描述

方式2:for循环一行生成迭代器

result = (i for i in range(10))

# 只有在调用迭代器的时候,for循环中的成员才会被放入迭代器中
print(next(result))

print(next(result))

结果:
在这里插入图片描述

return和yield的区别

  • 相同点:都是执行到关键字时会把结果返回
  • 不同点:return返回结果后,会结束当前函数的调用;yield返回结果后,暂停执行并记录当前执行的位置,下一次调用会从上次执行的位置后向下执行

例1:return

def t():
    print('this 1')
    return 1
    print('this 2')
    return 2

t = t()
print(t)
print(t)

根据结果可知:在运行到第一个return后,返回值1,后面的代码不会再执行了

例2:

def t():
    print('this 1')
    yield 1
    print('this 2')
    yield 2

t = t()
print(next(t))
print(next(t))

根据结果可知:

  • 执行第一个next(),运行到第一个yield并返回值1,暂停执行,并记录此时的位置
  • 执行第二个next(),运行到第二个yield并返回值2,暂停执行,并记录此时的位置
  • 若是再执行一个next(),因为后面已经没有yield了,迭代器中没有数据,所有此时会报错

总结:

  • 迭代器是能够被next()函数调用并不断返回下一个值的对象;
  • 生成器是一种特殊的迭代器,生成器函数返回的是一个迭代器;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值