我是靠谱客的博主 天真云朵,最近开发中收集的这篇文章主要介绍彻底理解 Python 迭代器与生成器1.为什么要有迭代器?2.迭代器的工作原理3.生成器的工作原理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

  • 1.为什么要有迭代器?
  • 2.迭代器的工作原理
    • 2.1.可迭代对象
      • 2.1.1. 什么是迭代对象?
      • 2.1.2. 可迭代对象有什么用?
    • 2.2.for循环与迭代器
  • 3.生成器的工作原理

1.为什么要有迭代器?

列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。

仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

那怎么做到只访问一两个元素,而不加载全部元素呢?迭代器可以做到。

例1(感受一下迭代器的作用)


t = [x * x for x in range(10)]
L = []
count = 0

g = iter(t)

while len(L) <= 10 :
    try:
        item = next(g)
        count += 1
        print(f'调用next()第{count}次获得的值为:{item}')
        L.append(item)
    except StopIteration:
        print('n迭代完成n')
        break

print(L,'n')
调用next()第1次获得的值为:0
调用next()第2次获得的值为:1
调用next()第3次获得的值为:4
调用next()第4次获得的值为:9
调用next()第5次获得的值为:16
调用next()第6次获得的值为:25
调用next()第7次获得的值为:36
调用next()第8次获得的值为:49
调用next()第9次获得的值为:64
调用next()第10次获得的值为:81

迭代完成

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

对于上面的列表 t ,往往每次只需要处理其中的一个元素。

如果不进行迭代处理,每次处理就需要把整个列表计算出来并加载到内存中来,而每次仅处理一个元素,这样是非常消耗内存。

况且这里的列表 t 还很小,假设这个列表变得有有成千上万上亿的元素,每次加载到内存,会占很大的内存空间,但是每次还是只处理一个元素,这样的内存消耗是非常巨大的

而进行了迭代处理,我并不需要每次都把整个列表 t 计算并加载出来,我只需要每次需要元素的时候,再计算那个元素,比如我需要第一个元素,计算出来加载到内存中,其他的元素则无需管。——每次只加载一个元素到内存,内存消耗会小很多。

总之:迭代器在循环处理大量数据的时候,能够减少非常多不必要的内存消耗。

2.迭代器的工作原理

说到迭代器又不得不说说可迭代对象

先一个一个捋清楚

2.1.可迭代对象

2.1.1. 什么是迭代对象?

就是可以迭代的对象,迭代就是每次只一次访问一个值,下次再访问下一个值。

可迭代对象有:字符串、列表、元组、字典、集合等等。

凡是可以for循环的对象都是可迭代对象,如列表的迭代,用for循环,每次获取list的一个值,下次获取下一个值。

例2

List = [1,2,3,4,5]
count = 0

for item in List:
    count = count + 1
    print(f'第{count}次获取的值:{item}')
第1次获取的值:1
第2次获取的值:2
第3次获取的值:3
第4次获取的值:4
第5次获取的值:5

2.1.2. 可迭代对象有什么用?

每个可迭代对象内置方法有:__iter__()、__next__()。

  • __next__()方法:
    此方法是可迭器能够迭代的关键,每次调用__next__()可以获取下一个值,然后停下来,再次调用又可以获取下一个值,直到__next__()抛出 StopIteration 异常,这个异常表示迭代完成。但是能够调用此方法的前提是:可迭代对象变成了迭代器,仅仅是迭代对象是不能调用此方法的(不能迭代)。那怎么把迭代对象变成迭代器呢?

  • __iter__()方法:
    作用于可迭代对象后,返回一个迭代器,只有迭代器才能真正进行迭代(才能进行调用__next__()方法)

__iter__
可迭代对象
迭代器

可迭代对象调用了__iter__()方法就可以迭代器

可迭代对象的__iter__()方法由python的内置函数iter()调用

可迭代对象的 __next__()方法由python内置函数next()调用

总的来说:迭代器由可迭代对象而来,迭代器能够进行迭代,可迭代对象则不能。

例3(可迭代对象没有变成迭代器进行迭代)✘

List = [1,2,3,4,5]	# 一个可迭代对象list

print(next(List))
TypeError: 'list' object is not an iterator

例4(可迭代对象转成迭代器进行迭代)✔

List = [1,2,3,4,5]

li = iter(List)
print(next(li))
print(next(li))
print(next(li))
print(next(li))
print(next(li))
1
2
3
4
5

2.2.for循环与迭代器

for循环本质上就是将可迭代对象转成迭代器,每一次循环调用一次 next(),直到捕获到 StopIteration 异常,停止循环。

例5(与例1如出一撤,这里用for实现)

t = [x * x for x in range(10)]
count = 0
L = []

for item in t:
	count += 1
	print(f'调用next()第{count}次获得的值为:{item}')
	L.append(item)
调用next()第1次获得的值为:0
调用next()第2次获得的值为:1
调用next()第3次获得的值为:4
调用next()第4次获得的值为:9
调用next()第5次获得的值为:16
调用next()第6次获得的值为:25
调用next()第7次获得的值为:36
调用next()第8次获得的值为:49
调用next()第9次获得的值为:64
调用next()第10次获得的值为:81

迭代完成

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

for循环其实就是迭代器的使用,只不过for循环方便了我们使用迭代器,省去了很多代码。

3.生成器的工作原理

生成器本质上就是一个迭代器,可以利用next()进行迭代。只不过这个迭代器的对象是一个函数(大部分都是)。

生成器是迭代器的一个应用,是函数的一种形式,使用了 yield 的函数被称为生成器(generator)。

yield可以返回一个或多个值,并记住当前位置。 其实就是替代了原来的return,return执行过后会重新来过,不标记任何位置,每次都全部执行一遍然后返回一个或多个值。

每次调用生成器,yield会返回一个指定值(或不返回),并标记当前位置。下次再调用它时,从yield标记的位置开始执行。直到抛出 StopIteration 停止迭代。

这样做的好处也是减少不必要的内存损耗,因为有些场景不需要每次调用函数都把循环内容重新过一遍。

例6(用next()迭代)

A = 1
B = 1
C = 0

def ADD():  # 生成器

    for _ in range(3):
        global A, B, C
        i = A + B
        C += i
        yield C

    return C

f = ADD()
while True:
    try:
        print (next(f))
    except StopIteration:
        print('n迭代完成')
        break
2
4
6

迭代完成

例7(用for迭代)

A = 1
B = 1
C = 0

def ADD():  # 生成器

    for _ in range(3):
        global A, B, C
        i = A + B
        C += i
        yield C

    return C

f = ADD()
for item in f:
    print(item)
print('n迭代完成n')
2
4
6

迭代完成

最后

以上就是天真云朵为你收集整理的彻底理解 Python 迭代器与生成器1.为什么要有迭代器?2.迭代器的工作原理3.生成器的工作原理的全部内容,希望文章能够帮你解决彻底理解 Python 迭代器与生成器1.为什么要有迭代器?2.迭代器的工作原理3.生成器的工作原理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部