美文网首页
python 可迭代对象 迭代器 生成器 概念、场景、判断方法

python 可迭代对象 迭代器 生成器 概念、场景、判断方法

作者: 牛奶大泡芙 | 来源:发表于2020-07-13 17:41 被阅读0次

关于迭代器生成器和可迭代对象比较容易混淆,虽然在实际代码中可能清楚地知道自己要写哪一种
下面会介绍
(一)可迭代对象、迭代器、生成器常用的场景
(二)可迭代对象、迭代器、生成器概念和方法
(三)如何判断变量是可迭代对象、迭代器还是生成器
***************************************** 一 ***********************************************
理解概念可以结合常用的使用场景,这或许就是概念定义的初衷
一般我们看见的一种用法是
比如:

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

在这里list就是一个可迭代对象,具有“iter”方法
it变成了迭代器,具有“next”方法,“next”方法可以依次单向取出it中的元素
这个场景算是很常见的了,记住这个场景就不难理解“可迭代对象”和“迭代器”
关于生成器,比较经典的一种是“菲波那切数列”

def fib(num):
    a,b,counter = 0,1,0
    while True:
        if counter > num:
            return
        yield a
        a,b = b, a+b
        counter += 1
f = fib(10)
print(next(f))

fib函数的特点就是用yield关键字来标识新元素的位置。可以发现fib函数返回的f又可以调用“next”方法了,以依次单向读取元素,也就是迭代器了,生成器生成了一个迭代器(在不使用“iter”方法的情况下)
***************************************** 二 ***********************************************
下面介绍三个概念:
1、 可迭代对象
可以直接作用于for循环的对象
只要定义了iter()就是可迭代对象
例子1:
dict,list,string

2、 迭代器
是遍历元素集合的一种方法,可以记住上次读取元素的位置,并通过next方法继续读取下一个元素
是for循环实际上操作的对象
把一个类作为迭代器使用,需要实现iter,next两个
迭代器只能向前不能后退,不具有撤销性
两个基本方法:iter(), next()
例子1:
Iter(dict), iter(list), iter(string)可以直接for循环操作

例子2:

class MuNumbers:
    def __iter__(self):
        self.a = 1
        return self
    def __next__(self):
        if self.a < 20:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration
# 实例化
m = MyNumbers()
m_iter = iter(m)
print(next(m_iter))

3、 生成器
一个返回迭代器的函数,只能用于迭代操作
作用之一是节省内存,它可以在循环中计算,一边生成数据一边不占内存,因为每个数据使用的是一个变量
例子1:

G = (i+a for I in list1 for a in list2)

调用方法:next(G)
例子2:
如下的斐波那契生成器函数

比较常见的一个生成器函数是斐波那契,调用的方法是多样的,参考??代码

def fib(num):
    a,b,counter = 0,1,0
    while True:
        if counter > num:
            return
        yield a
        a,b = b, a+b
        counter += 1

f = fib(10)

print(next(f))
print(next(f))
print(next(f))
print(next(f))
print('*******')
print(f.__next__())
print(f.__next__())
print('*******')
print([i for i in f])

运行结果是这样的,可以看见next和next函数的调用效果相同,可以使生成器函数内部的数据向前移动,导致了最终遍历的时候遍历不到,其实for循环的实际操作也是按照相同的方法向下迭代的

0
1
1
2
*******
3
5
*******
[8, 13, 21, 34, 55]

***************************************** 三 ***********************************************
用collections判断list的类型,运行效果如下:

list类型判断.png
可以看出,list是可迭代对象而不是迭代器,拥有iter()方法,没有next()方法,并且在调用了iter()方法之后就变成了迭代器。

实例化的MyNumbers具有iter方法和next方法,既是可迭代对象也是迭代器,测试结果如下:


MyNumbers类型判断.png

而且m与m_iter指向同一个对象

判断inspect判断生成器


inspect检测生成器.png

相关文章

网友评论

      本文标题:python 可迭代对象 迭代器 生成器 概念、场景、判断方法

      本文链接:https://www.haomeiwen.com/subject/pmkzcktx.html