Python迭代器和生成器

前言

迭代器和生成器都是对可迭代的对象进行操作。

迭代器

  • 迭代是Python最强大的功能之一,是访问集合元素的一种方式。

  • 迭代器是一个可以记住遍历的位置的对象。

  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

  • 迭代器有两个基本的方法:iter() 和 next()。

迭代器的优点:

  1. 可节省内存空间

  2. 会从容器里面挨个取值,直到取完为止

迭代器的缺点

  1. 对迭代对象的取值不够灵活,只能从下一个开始

  2. 无法判断迭代器的长度

示例

list = [1,2,3,4]
nums = iter(list)
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))

list = [1,2,3,4]
nums = iter(list)
for i in nums:
    print(i)

list = [1,2,3,4]
nums = iter(list)
while True:
    try:
        print(next(nums))
    except StopIteration:
        break

生成器

  • 在 Python 中,使用了 yield 的函数被称为生成器(generator)。

  • 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

  • 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

  • 调用一个生成器函数,返回的是一个迭代器对象。

生成器的优缺点

生成器本质上是迭代器,所以继承迭代器的所有优缺点。

生成器对比普通循环

import sys
#查看占用内存大小
mylist = [i for i in range(10000000)]
print(type(mylist))
print('列表占用内存大小:',sys.getsizeof(mylist),'字节')
mygen = (i for i in range(10000000))
print(mygen)
print('生成器占用内存大小:',sys.getsizeof(mygen),'字节')


内存大小一目了然,内存数据相差万倍。所以采用生成器能有效优化数据占用量,尤其在读取大量的日志文件能有效避免内存溢出的错误。

示例

第一种方法很简单,只要把一个列表生成式的[]改成(),就创建一个生成器(generator)。

ls = [x*x for x in range(10)]
print(type(ls))
print(ls)

ls2 = (x*x for x in range(10))
print(ls2)
for i in ls2:
    print(i,end=',')


第二种方法,函数使用yield关键字,则它就是一个生成器。
yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

def a(x):
    for i in range(x): 
        yield i*i
s = a(5)
print(s)
for i in s:
    print(i)

#生成器创建斐波那契数列
def fb(n):
    a,b = 0,1
    for i in range(n):
        yield b
        a,b = b,a+b

f = fb(10)
for i in f:
    print(i,end=',')

posted @ 2020-11-10 23:09  Harry_666  阅读(153)  评论(0编辑  收藏  举报