python 可迭代对象和迭代器


前言

对于刚刚进入python学习的小伙伴来说,可迭代对象和迭代器的概念有点难以理解,今天笔者想在此讲解下二者的联系和区别,有错误之处,还请各位大佬指正


一、什么是迭代?

迭代是访问集合元素的一种方式;我们把通过for…in…语句这样进行遍历的过程称为迭代

二、什么是可迭代对象(Iterable)

1.可迭代对象的定义

我们通常把可以通过for…in…语句进行遍历的对象,称之为可迭代对象(Iterable)

for i in range(5):
	print(i, end=' ') 
# 输出:0 1 2 3 4
# range(5)的返回值,就是一个可迭代对象

2.怎么判断一个对象是不是可迭代对象

可以通过isinstance方法来判断一个对象是不是可迭代对象

from collections.abc import Iterable

print(isinstance([], Iterable))  # True
print(isinstance('', Iterable))  # True
print(isinstance((), Iterable))  # True
print(isinstance(set(), Iterable))  # True
print(isinstance({}, Iterable))  # True
print(isinstance(range(5), Iterable))  # True
print(isinstance(4, Iterable))  # False
print(isinstance(True, Iterable))  # False

3.自定义可迭代对象

知道了怎么判断一个对象是不是可迭代对象之后,那创建对象的类要符合什么样的条件,才能使得他创建的对象是可迭代对象呢?

from collections.abc import Iterable


class A(object):
    def __init__(self):
        super().__init__()


class B(object):
    def __init__(self):
        super().__init__()

    def __iter__(self):
        pass


print(isinstance(A(), Iterable))  # False
print(isinstance(B(), Iterable))  # True
# 可以看出,B类与A类相比,只多了一个__iter__方法

一个实现了__iter__方法的类创建的对象,都是可迭代对象

然后尝试直接进行遍历:

class B(object):
    def __init__(self):
        super().__init__()

    def __iter__(self):
        pass


for i in B():
    print(i)


# 运行会报错 -> TypeError: iter() returned non-iterator of type 'NoneType'

可见,单纯实现了__iter__并不支持进行遍历,__iter__对象还需要返回一个迭代器(Iterator),才可以遍历


三、什么是迭代器(Iterator)

1.迭代器的定义

迭代的过程中,迭代器起着,帮助我们记录迭代位置的作用,从而可以依次由前向后获取序列中的数据

我们在迭代一个可迭代对象的时候,就是先通过__iter__方法获取到该对象提供的迭代器,再通过这个迭代器,依次获取对象中的每一个数据


2.怎么判断一个对象是不是迭代器

可以通过isinstance方法来判断一个对象是不是迭代器

from collections.abc import Iterator

print(isinstance([], Iterator))  # False
print(isinstance(iter([]), Iterator))  # True

print(isinstance('', Iterator))  # False
print(isinstance(iter(''), Iterator))  # True

print(isinstance((), Iterator))  # False
print(isinstance(iter(()), Iterator))  # True

print(isinstance(set(), Iterator))  # False
print(isinstance(iter(set()), Iterator))  # True

print(isinstance({}, Iterator))  # False
print(isinstance(iter({}), Iterator))  # True

3.自定义迭代器

知道了怎么判断一个对象是不是迭代器之后,那创建对象的类要符合什么样的条件,才能使得他创建的对象是迭代器呢?

from collections.abc import Iterator

class A(object):
    def __init__(self):
        super().__init__()


class B(object):
    def __init__(self):
        super().__init__()

    def __iter__(self):
        pass


class C(object):
    def __init__(self):
        super().__init__()

    def __iter__(self):
        pass

    def __next__(self):
        pass


print(isinstance(A(), Iterator))  # False
print(isinstance(B(), Iterator))  # False
print(isinstance(C(), Iterator))  # True
# 可以看出,C类与A类相比,只多了__iter__方法和__next__方法

一个实现了__iter__方法和__next__方法的类创建的对象,都是迭代器


四、自定义可迭代对象和迭代器实现遍历

1.__next__方法的作用

前文讲过,__iter__方法可以提供一个迭代器,帮助我们,在迭代的过程中记录位置,而__next__方法的作用就是返回迭代时序列中的值,依次往后变化


2.自定义可迭代对象和迭代器实现遍历

接下来,我们自定义一个可迭代对象的类,和一个迭代器的类,实现自定义对象的迭代

class MyIterable(object):
    def __init__(self):
        pass

    def __iter__(self):
        my_iterator = MyIterator()
        return my_iterator


class MyIterator(object):
    def __init__(self):
        self.list = [1, 2, 3]
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.list):
            res = self.list[self.index]
            self.index += 1
            return res
        else:
            raise StopIteration


for i in MyIterable():
    print(i, end=' ')
# 输出: 1 2 3

总结

总结要点如下:
1、用for循环遍历的对象一定是可迭代对象
2、只实现了__iter__方法的类创建的对象,是可迭代对象
3、实现了__iter__方法和__next__方法的类创建的对象,是迭代器
4、__iter__方法需要返回一个迭代器,用于在迭代过程中帮忙记录位置;__next__方法的返回值就是遍历过程中得到的值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值