Python 迭代器与生成器

简介

迭代是Python访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象,而生成器则是实现迭代器协议的生成数据的简单函数。迭代器只能往前不会后退,而生成器可以。迭代器和生成器都是Python中强大的数据类型,具有惰性计算的特点,即不会立即产生所有结果,而是逐步产生。

迭代器(Iterator)

迭代器是一个对象,可以用来遍历可迭代对象(如列表、元组、字典等)中的元素。迭代器是一个具有__next__方法的对象,每次调用__next__方法时,迭代器会返回它的下一个值。如果迭代器没有更多的值可以返回,调用__next__方法会引发一个StopIteration异常。迭代器只能往前不会后退,这意味着无法重新访问已经遍历过的元素。迭代器可以用于遍历大型数据集,因为它们在内存中只存储一个元素,而不是一次性加载整个数据集。

__iter__方法返回迭代器本身,通常是self。
__next__方法返回可迭代对象的下一个元素,如果没有元素可迭代,会引发StopIteration异常。

简单示例

class MyIterator:
    def __init__(self, data):  # 初始化
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration  # 抛出异常
        value = self.data[self.index]
        self.index += 1
        return value

my_iter = MyIterator([1, 2, 3, 4, 5])
for item in my_iter:
    print(item)

二叉树中序遍历

# 定义二叉树节点类
class BinaryTree(object):
    def __init__(self, value, left=None, right=None):
        self.value = value  # 节点值
        self.left = left  # 左子树
        self.right = right  # 右子树

    def __iter__(self):
        return InorderIterator(self)

# 定义中序遍历的迭代器类
class InorderIterator(object):
    def __init__(self, node):
        self.node = node  # 当前节点
        self.stack = []  # 用于辅助中序遍历的栈

    def __next__(self):
        # 如果栈非空或者当前节点非空
        if len(self.stack) > 0 or self.node is not None:
            while self.node is not None:
                self.stack.append(self.node)  # 将当前节点入栈
                self.node = self.node.left  # 移动到左子树
            node = self.stack.pop()  # 弹出栈顶节点
            self.node = node.right  # 移动到右子树
            return node.value  # 返回节点的值
        else:
            raise StopIteration()  # 遍历完成时抛出异常

# 创建一个二叉树
tree = BinaryTree(
    left=BinaryTree(
        left=BinaryTree(1),
        value=2,
        right=BinaryTree(
            left=BinaryTree(3),
            value=4,
            right=BinaryTree(5)
        ),
    ),
    value=6,
    right=BinaryTree(
        value=7,
        right=BinaryTree(8)
    )
)

for value in tree:
    print(value)

上述代码定义了一个二叉树和中序遍历的迭代器,然后使用迭代器来遍历树的节点并打印节点的值。

生成器(Generator)

生成器是一种特殊的迭代器,可以通过函数来创建。生成器函数使用yield关键字来产生值,而不是使用return。实际上,生成器是实现迭代器协议的生成数据的简单函数,本质上属于迭代器。生成器用于“凭空”生成元素,每次调用生成器的函数时,它都会计算一个新的值,并将其添加到结果集中。生成器函数在每次调用时不会重新启动,而是从上一次yield语句的位置继续执行。生成器在迭代时会自动管理状态,不需要手动实现 __iter____next__方法。

简单示例

def my_generator(data):
    for item in data:
        yield item

gen = my_generator([1, 2, 3, 4, 5])
for item in gen:
    print(item)

二叉树中序遍历

# 定义二叉树节点类
class BinaryTree(object):
    def __init__(self, value, left=None, right=None):
        self.value = value  # 节点的值
        self.left = left  # 左子树
        self.right = right  # 右子树

# 使用生成器实现中序遍历的函数
def traversal(node):
    if node is not None:
        yield from traversal(node.left)  # 递归左子树
        yield node.value  # 生成当前节点的值
        yield from traversal(node.right)  # 递归右子树

# 创建一个二叉树
tree = BinaryTree(
    left=BinaryTree(
        left=BinaryTree(1),
        value=2,
        right=BinaryTree(
            left=BinaryTree(3),
            value=4,
            right=BinaryTree(5)
        ),
    ),
    value=6,
    right=BinaryTree(
        value=7,
        right=BinaryTree(8)
    )
)

# 使用生成器进行中序遍历并打印节点值
for value in traversal(tree):
    print(value)

总结

总而言之,Python的迭代器是一种可以遍历集合中元素的对象,必须实现__iter____next__方法。__iter__返回迭代器自身,__next__用于获取下一个元素,当没有元素可迭代时,会引发StopIteration异常。

生成器则是一种特殊的迭代器,使用函数中的yield关键字来生成值,但不会中断函数的执行。生成器提供了一种更简洁的方式来创建可迭代对象,它按需生成元素,因此可以节省内存。生成器函数在每次调用yield时会保存当前状态,以便下次从相同位置继续执行,使得迭代更加灵活和高效,在处理大规模数据集时非常有用。

你可能感兴趣的:(Python,python)