python的迭代器---Iterable和iterator

迭代器—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

看起来是不是很难受

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

猜你喜欢

转载自blog.csdn.net/qq13933506749/article/details/130563029