当前位置:   article > 正文

超详细!Python 迭代器--详细整理

python 迭代器

Python 迭代器

1 迭代器

Python 的迭代器机制,可以实现简单高效的遍历容器中的元素,迭代器(iterator)是一种使得我们可以遍历容器对象的方式。它是一个对象,能够让代码在处理序列时,避免使用难以维护的索引变量。

迭代器的作用:

  1. 遍历容器中的元素:迭代器提供了一种逐个访问容器中元素的方法,可以遍历一个容器,访问其中的每个元素。
  2. 节省内存消耗:使用迭代器可以节省内存消耗,因为它只保存当前迭代的元素和迭代状态,而不是保存整个容器的数据。
  3. 实现惰性求值:迭代器采用的是延迟计算的方式,只有在需要时才会计算下一个元素,可以在处理大量数据时减少计算量。
  4. 处理无限序列:使用迭代器可以处理无限序列,因为它只需要在需要时生成下一个元素,而不需要一次性生成整个序列。
  5. 支持for循环:Python中for循环底层基于迭代器实现,因此,任何支持迭代的对象都可以用于 for 循环语句中。
  6. 处理流式数据:迭代器可以处理流式数据,比如网络数据、文件数据等,可以逐次读取大文件中的数据,或者逐次处理流式数据,而不必一次性将所有数据读入内存。
  7. 更加简洁的代码:使用迭代器可以减少代码的复杂度,提高代码的可读性和可维护性。因为迭代器提供了一种逐个访问元素的方法,可以避免使用复杂的控制流语句等。

迭代器机制的优点主要包括:

  • 节省内存,提高效率。迭代器是一种惰性求值策略,只有在遍历过程中才返回真正需要的数据,避免了一次性读取全部数据带来的内存消耗和时间开销。
  • 支持无限序列处理。由于迭代器可以一次返回一个元素,因此对于很多无限序列(比如自然数序列)的遍历,使用迭代器可以实现简单高效的处理。
  • 利于数据流处理。迭代器可以接受输入流的数据,逐一处理每一份数据,并适时输出处理结果,符合数据流“拉取式”处理的特点。

迭代器机制的缺点主要包括:

  • 无法回溯。一旦迭代器遍历到某个位置,就无法往回遍历。因此,如果需要反复遍历一个序列对象,就需要重新构造一个新的迭代器或者使用其他数据结构。
  • 代码可读性不够好。相比于传统的 for 循环语句,使用迭代器来遍历容器需要编写更多的代码,可读性略有下降。

迭代器的应用场景:

  1. 处理大型数据集时,使用迭代器可以节省大量内存空间。
  2. 迭代器可以用于处理网络请求中返回的大型数据流。
  3. 迭代器可以用于实现自定义数据结构,例如链表和树等。

Python 的迭代器机制可以用来简化很多常见的数据处理任务,比如:

  • 遍历列表、元组等序列对象
  • 遍历字典中的键或值
  • 遍历文件的每一行
  • 处理无限序列
  • 实现惰性计算等

1.1 迭代器的基本概念

在 Python 中,迭代器是一个实现了迭代协议的对象。所谓迭代协议,指的是对象实现了 __iter____next__ 两个方法。其中,

  • __iter__ 方法返回迭代器对象本身。
  • __next__ 方法返回容器中的下一个元素。如果容器中没有更多的元素,那么就抛出 StopIteration 异常。

因此,从迭代器的实现形式来看,迭代器是一种 “惰性” 的遍历器。它不会一次性将容器中的所有元素全部返回,而是实现了一次只返回一个元素的效果。这样一来,在处理数据量较大的情况下,迭代器可以节省大量的系统内存,并且能够更好地支持处理流式数据。

1.2 实现迭代器的两种方式

在 Python 中,实现迭代器的方式有两种:使用类和生成器。

1.2.1 使用类

实现迭代器最常用的方法就是自定义一个类,并在类的内部实现迭代协议。比如,下面是一个简单的迭代器类,可以用来遍历一个实现了 __getitem__ 方法的序列对象:

class MyIterator:
    def __init__(self, seq):
        self.seq = seq
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.seq):
            raise StopIteration
        result = self.seq[self.index]
        self.index += 1
        return result

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个迭代器类中,我们定义了两个属性 seqindex,分别代表了要遍历的序列对象和当前遍历的位置。在遍历时,每次都返回当前位置的元素,并将位置加一。如果到达序列的末尾,那么就抛出 StopIteration 异常。

1.2.2 使用生成器

除了使用类实现迭代器外,Python 还提供了一种叫做生成器的机制,可以更加简洁地实现迭代器。生成器的本质也是一种迭代器,只不过是通过函数来实现。比如,下面是一个利用生成器实现的迭代器,可以用来遍历一个包含了多个序列对象的列表:

def multi_iter(seq_list):
    for seq in seq_list:
        for item in seq:
            yield item

  • 1
  • 2
  • 3
  • 4
  • 5

在这个生成器函数中,我们通过两个嵌套的 for 循环来遍历多个序列对象,每次迭代返回一个元素,利用 yield 语句实现,生成器会在每次迭代时自动记录下当前的状态,并在下次调用 next() 方法时从这个状态开始继续执行。


生成器是一种特殊的函数,使用 yield 语句返回一个迭代器。简单来说,生成器可以看做是一个可暂停执行的函数,当函数需要返回一个值时,可以使用 yield 返回一个值,之后函数的状态会被保存下来,等待下一次继续执行。

以下是使用生成器创建迭代器的示例代码:

# 定义一个生成器,返回一个迭代器
def my_generator():
    yield 1
    yield 2
    yield 3

# 使用 next() 函数访问迭代器
my_iterator = my_generator()
print(next(my_iterator)) # 输出第一个元素 1
print(next(my_iterator)) # 输出第二个元素 2
print(next(my_iterator)) # 输出第三个元素 3

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面的代码中,我们定义了 my_generator() 函数,使用 yield 语句返回一个迭代器。在程序中调用 my_generator() 函数之后,返回的是一个生成器对象,可以通过 next() 函数逐一获取生成器内保存的值。

虽然生成器本质上也是一种迭代器,但是它们之间还是有一些区别的。具体来说:

  • 生成器可以通过函数来定义,而传统的迭代器需要定义一个类。
  • 生成器可以用更加简洁的语法实现,只需要使用 yield 语句即可。
  • 生成器只能通过一遍性地遍历序列对象,无法实现重复迭代;而传统的迭代器则可以在每次遍历之间保留状态,实现重复迭代。
---------------------------END---------------------------

题外话

当下这个大数据时代不掌握一门编程语言怎么跟的上时代呢?当下最火的编程语言Python前景一片光明!如果你也想跟上时代提升自己那么请看一下.

在这里插入图片描述

感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/145693
推荐阅读
相关标签