2.16_迭代器与可迭代对象!

85 阅读4分钟

2.16 迭代器与可迭代对象

2.16.1 迭代器的概念

2.16.1.1 迭代器与可迭代对象的区别

# 可迭代对象是可以被迭代的对象,比如列表、元组、字符串等
iterable = [1, 2, 3]
# 迭代器是一个有迭代状态的对象,可以一一产生可迭代对象的元素
iterator = iter(iterable)
​
# 迭代器可以从可迭代对象获得
print(isinstance(iterable, Iterable))  # True,因为列表是可迭代对象
print(isinstance(iterator, Iterator))  # True,因为iter函数返回迭代器

输出:

True
True

解释: 可迭代对象有一个__iter__()方法,返回一个迭代器。迭代器有一个__next__()方法,用于返回下一个元素。

2.16.1.2 iter()next()函数的工作原理

# iter()函数接受一个可迭代对象,并返回一个迭代器
my_list = [1, 2, 3]
my_iter = iter(my_list)
​
# next()函数接受一个迭代器,并返回它的下一个元素
print(next(my_iter))  # 输出 1
print(next(my_iter))  # 输出 2

输出:

1
2

解释: iter()函数获取对象的迭代器,next()函数从迭代器中获取下一个元素。

2.16.1.3 实现迭代器协议的要求(__iter__()__next__()

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):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration
​
# 使用自定义迭代器
my_data = [1, 2, 3]
my_custom_iterator = MyIterator(my_data)
for item in my_custom_iterator:
    print(item)

输出:

1
2
3

解释: 自定义迭代器必须实现__iter__()返回迭代器自身,__next__()返回下一个元素,当没有元素时抛出StopIteration

2.16.1.4 使用迭代器简化数据遍历

# 使用迭代器遍历数据
my_iter = iter([1, 2, 3])
for num in my_iter:
    print(num)

输出:

1
2
3

解释: 迭代器允许我们逐个访问元素,而不需要关心数据的具体结构。

2.16.2 创建可迭代对象

2.16.2.1 可迭代对象的定义

# 可迭代对象定义为有一个__iter__()方法的对象
my_list = [1, 2, 3]
print(hasattr(my_list, '__iter__'))  # 输出 True

输出:

True

解释: 列表等内置类型都是可迭代对象。

2.16.2.2 实现可迭代对象协议的要求(__iter__()方法)

class MyIterable:
    def __iter__(self):
        return iter([1, 2, 3])

my_iterable = MyIterable()
for item in my_iterable:
    print(item)

输出:

1
2
3

解释: 可迭代对象需要实现__iter__()方法,返回一个迭代器。

2.16.2.3 使用for循环遍历可迭代对象

# for循环本质上是在使用迭代器
for char in "批量小王子":
    print(char)

输出:

批
量
小
王
子

解释: for循环自动调用__iter__()__next__()

2.16.2.4 自定义可迭代对象的实现

class MyCollection:
    def __init__(self, elements):
        self.elements = elements

    def __iter__(self):
        for elem in self.elements:
            yield elem

my_collection = MyCollection([1, 2, 3])
for elem in my_collection:
    print(elem)

输出:

1
2
3

解释: 自定义可迭代对象通过yield实现__iter__()

2.16.2.5 可迭代对象的内存效率与优化

# 可迭代对象可以节省内存,因为它不需要一次性将所有元素加载到内存
class LazyRange:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop

    def __iter__(self):
        current = self.start
        while current < self.stop:
            yield current
            current += 1

# 使用懒加载范围
for num in LazyRange(0, 1000000):
    if num > 100:  # 只处理前100个数字
        break

输出:

0
1
...
100

解释: 懒加载可迭代对象可以节省内存,因为它不需要一次性创建所有元素。

2.16.3 内置函数iter()和next()的使用

2.16.3.1 iter()函数的用法与实现

# iter()函数用法
my_iterable = [1, 2, 3]
my_iterator = iter(my_iterable)
print(next(my_iterator))  # 输出 1

输出:

1

2.16.3.2 next()函数的用法与错误处理(如StopIteration

# next()函数用法和错误处理
my_iterator = iter([1, 2, 3])

try:
    print(next(my_iterator))
    print(next(my_iterator))
    print(next(my_iterator))
    print(next(my_iterator))  # 将抛出StopIteration
except StopIteration:
    print("没有更多元素")

输出:

1
2
3
没有更多元素

2.16.3.3 使用next()遍历迭代器中的元素

# 使用next()遍历元素
my_iterator = iter([1, 2, 3])
while True:
    try:
        print(next(my_iterator))
    except StopIteration:
        break

输出:

1
2
3

2.16.3.4 next()for循环的关系

# for循环内部使用next()
for elem in [1, 2, 3]:
    print(elem)

输出:

1
2
3

解释: for循环内部会调用iter()获取迭代器,然后不断调用next()直到抛出StopIteration

这些代码示例提供了迭代器和可迭代对象的概念、创建和使用,以及iter()next()函数的详细说明。您可以在本地环境中执行这些代码来验证输出。

4-1-2.png