python的迭代器---Iterable和iterator

文章详细解释了Python中的迭代器(Iterator)和可迭代对象(Iterable)的概念,通过示例展示了如何使用__iter__和__next__方法实现自定义迭代器。文中指出,一个迭代器需要有__next__方法来返回下一个值,而可迭代对象需要能返回一个迭代器,通常通过__iter__方法实现。当迭代器没有__iter__方法时,无法直接进行二次迭代,修复方法是在迭代器类中添加__iter__方法使其也成为可迭代对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迭代器—Iterable和iterator

举例

test_list = [1, 2, 3]

test_dump = {"name": "zhangsan", "age": "12"}

for i in test_list:
    print(i)
    print(type(i))

for key in test_dump:
    print(key)
    print(test_dump[key])
    print(type(key))

结果

1
2
3
name
zhangsan
age
12

Iterable和iterator

先说概念

Iterable 可迭代对象,for loop的 in 后面必须是一个Iterable 数据的保存者,可以没有状态,他不必知道iterator数到了哪里,但是必须有能力产生一个iterator
一个Iterable,要么有__iter__这个method,要么就需要是一个sequence(顺序排列,队列),有__getitem__这个method,这两个都是为了保证可以返 回一个iterator。
iterator 迭代器,表示数据流的对象,iterator必须是有状态的,但是并不需要实现一个Iterable,一个iterator必须要有__next__这个方法,这个method保证他在被 next作用的时候,可以返回下一个Iterable里的值,也就是一个新的iterator

for loop的时候会先对Iterable进行一个iter()操作,然后再根据iterator进行操作,加下来我们来理解一下上面这些概念的意思

class NodeIter:
    def __init__(self, node):
        self.curr_node = node

    def __next__(self):
        if self.curr_node is None:
            # 如果数据已经到头了,就需要抛出错误
            raise StopIteration
        # 没有到头的话,就返回这个node,并且把下一个值存储
        node, self.curr_node = self.curr_node, self.curr_node.next
        return node


class Node:
    def __init__(self, name):
        self.name = name
        self.next = None

    def __iter__(self):
        # Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
        return NodeIter(self)


node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3

for node in node1:
    # 等于for node in iter(node1),向Iterable要了一个iterator
    print(node.name)

结果

Node1
Node2
Node3 

但是呢官方推荐这个iterator除了有__next__函数之外,还需要有__iter__函数,是为了让每一个iterator也是一个Iterable,就是让每一个迭代器也是可迭代的

class NodeIter:
    def __init__(self, node):
        self.curr_node = node

    def __next__(self):
        if self.curr_node is None:
            # 如果数据已经到头了,就需要抛出错误
            raise StopIteration
        # 没有到头的话,就返回这个node,并且把下一个值存储
        node, self.curr_node = self.curr_node, self.curr_node.next
        return node


class Node:
    def __init__(self, name):
        self.name = name
        self.next = None

    def __iter__(self):
        # Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
        return NodeIter(self)


node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3

# 先求了一个iterator出来
it = iter(node1)
# 将iterator的第一个值取出来了
first = next(it)
# 再来迭代it这个iterator
for node in it:
    # 等于for node in iter(node1)
    print(node.name)

报错

TypeError: 'NodeIter' object is not iterable

为什么会报错,因为for node in x,是向x要了一个iterator,也就是调用iterable的__iter__魔法函数,现在你直接给我了一个iterator,而这个iterator是只有__next__函数的,是没有__iter__函数来返回一个iterator的。
看起来是不是很难受

class NodeIter:
    def __init__(self, node):
        self.curr_node = node

    def __next__(self):
        if self.curr_node is None:
            # 如果数据已经到头了,就需要抛出错误
            raise StopIteration
        # 没有到头的话,就返回这个node,并且把下一个值存储
        node, self.curr_node = self.curr_node, self.curr_node.next
        return node
    # 解决办法很简单,就是在iterator里也实现一个__iter__方法,返回他自己就可以了
    def __iter__(self):
        return self


class Node:
    def __init__(self, name):
        self.name = name
        self.next = None

    def __iter__(self):
        # Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
        return NodeIter(self)


node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3

# 先求了一个iterator出来
it = iter(node1)
# 将iterator的第一个值取出来了
first = next(it)
# 再来迭代it这个iterator
for node in it:
    # 等于for node in iter(node1)
    print(node.name)

结果

Node2
Node3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值