跳至主要內容

迭代器

blacklad大约 3 分钟PythonPython

迭代器

一、介绍

迭代

迭代是指重复执行某个过程。在编程中,迭代常用于遍历数据结构中的每一个元素,比如列表、元组或字符串。

可迭代对象

在 Python 中,可迭代对象是指可以使用 for 循环遍历的对象,比如列表、元组、字符串、字典和集合。这些对象都有一个内置方法 __iter__(),使得它们可以返回一个迭代器。

my_list = [1, 2, 3]
for item in my_list:
    print(item)
1
2
3

二、迭代器

迭代器是实现了迭代协议的对象,它们有两个方法:__iter__()__next__()__iter__() 返回迭代器对象本身,而 __next__() 返回容器的下一个元素,如果没有元素了,就会引发 StopIteration 异常。

通过内置函数,可以将 list 转为迭代器:

my_list = [1, 2, 3]
it = iter(my_list)
print(next(it))
print(next(it))
print(next(it)) 
print(next(it))  # 抛出 StopIteration 异常
1
2
3
Traceback (most recent call last):
  File ".../test_iter.py", line 6, in <module>
    print(next(it))  # 抛出 StopIteration 异常
StopIteration

三、使用场景

节省内存

迭代器是按需生成元素的,这意味着它们不会一次性将所有元素存储在内存中。相比于生成包含所有元素的列表或其他容器,迭代器可以节省大量内存,尤其是在处理大量数据时。

import sys

# 普通列表占用较多内存
my_list = [i for i in range(1000000)]
print(sys.getsizeof(my_list))  # 输出内存大小

# 迭代器占用较少内存
my_iterator = (i for i in range(1000000))
print(sys.getsizeof(my_iterator))  # 输出内存大小

my_iterator = (i for i in range(100000000))
print(sys.getsizeof(my_iterator))  # 输出内存大小
8697472
128
128

可以看出,对于迭代器占用了较少的内存,而且和数量没有关系。

惰性求值

迭代器使用惰性求值策略,即在需要时才生成下一个元素。这种特性使得迭代器在处理流式数据(如读取大文件)时特别有用,因为它们可以逐行读取文件,而不是一次性将整个文件读入内存。

def read_large_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            yield line

# 使用迭代器逐行读取大文件
for line in read_large_file('large_file.txt'):
    print(line.strip())

可无限序列

迭代器可以用于生成无限序列,比如斐波那契数列或无穷递增序列,而不会耗尽内存。这是因为迭代器不会一次性生成所有元素,只会在需要时生成下一个元素。

class Fibonacci:
    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        self.a, self.b = self.b, self.a + self.b
        return fib

# 创建一个迭代器实例
fib_iter = Fibonacci()


# 使用迭代器生成斐波那契数列
for num in fib_iter:
    if num > 10:
        break
    print(num)

0
1
1
2
3
5
8

在迭代的过程中实时计算,而不是提前都计算好。

四、生成器

生成器是一种特殊的迭代器,它通过 yield 关键字一次返回一个值。生成器比普通迭代器更简单易用,因为它不需要实现 __iter__()__next__() 方法。

def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
print(next(gen)) 
print(next(gen))
print(next(gen))
print(next(gen))  # 抛出 StopIteration 异常
1
2
3
Traceback (most recent call last):
  File ".../test_iter.py", line 10, in <module>
    print(next(it))  # 抛出 StopIteration 异常
StopIteration

生成器在调用时不会立即执行,而是返回一个生成器对象。每次调用 next() 方法时,生成器函数会继续执行,直到遇到 yield 语句,返回 yield 后面的值。再次调用 next() 时,生成器会从上次暂停的地方继续执行。

上次编辑于:
贡献者: blacklad