Python中迭代器与可迭代对象对比与区别

可迭代对象(Iterable)

什么是可迭代对象?

可迭代对象是指实现了__iter__()方法的对象,或者实现了一个能够返回迭代器的__getitem__()方法的对象。简单来说,可迭代对象可以通过for循环遍历,或者通过内置函数iter()将其转换为迭代器。常见的可迭代对象包括:

  • 序列类型:如list(列表)、tuple(元组)、str(字符串)、range(范围对象)
  • 集合类型:如set(集合)、frozenset(冻结集合)
  • 字典类型:如dict(字典)
  • 文件对象:如打开的文件(文件句柄)
  • 以及其他自定义实现了__iter__()或__getitem__()方法的对象

如何判断一个对象是否是可迭代对象?

可以使用collections.abc模块中的Iterable类来判断一个对象是否是可迭代对象:

from collections.abc import Iterable

print(isinstance([1, 2, 3], Iterable))  # True
print(isinstance("hello", Iterable))    # True
print(isinstance(123, Iterable))        # False

可迭代对象的特点

  1. 实现了__iter__()方法:当调用iter(obj)时,iter()方法返回一个迭代器对象(即实现了__next__()方法的对象)。
  2. 可以使用for循环遍历:for item in obj的背后就是在不断调用该对象的迭代器对象的__next__()方法。
  3. 支持多次迭代:每次调用iter()方法时,它都会返回一个新的迭代器,从而可以多次遍历。
# 列表是可迭代对象,可以多次迭代
my_list = [1, 2, 3]
for item in my_list:
    print(item)  # 输出1, 2, 3

for item in my_list:
    print(item)  # 再次输出1, 2, 3

迭代器

什么是迭代器?

迭代器是一个实现了__iter__()和__next__()方法的对象。迭代器与可迭代对象的区别在于,迭代器本身就是一个状态ful的对象,它可以逐个获取数据元素,而不像可迭代对象那样可以随时重置。迭代器的特点是:

  • 实现了__next__()方法:每次调用该方法时,它会返回下一个数据元素;如果没有更多元素,它会引发StopIteration异常。
  • 只能被遍历一次:一旦元素被迭代完毕,再次调用__next__()就会直接引发StopIteration异常

如何判断一个对象是否是迭代器?

我们可以使用collections.abc模块中的Iterator类来判断一个对象是否是迭代器:

from collections.abc import Iterator

my_iter = iter([1, 2, 3])  # 通过iter()将列表转化为迭代器
print(isinstance(my_iter, Iterator))  # True
print(isinstance([1, 2, 3], Iterator))  # False

迭代器的特点

  1. 实现了__iter__()方法,并且__iter__()返回自身。
  2. 实现了__next__()方法,该方法会返回迭代器的下一个元素。
  3. 状态ful:迭代器是有状态的对象,它记录了当前的遍历位置,一旦遍历完成就无法再次遍历。
# 使用迭代器
my_iter = iter([1, 2, 3])
print(next(my_iter))  # 输出 1
print(next(my_iter))  # 输出 2
print(next(my_iter))  # 输出 3
# print(next(my_iter))  # 再次调用会引发StopIteration异常

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

  1. 实现的接口不同
  • 可迭代对象必须实现__iter__()方法。
  • 迭代器必须实现__iter__()和__next__()方法
  1. 返回值不同
  • 调用iter()方法时,可迭代对象会返回一个新的迭代器对象。
  • 迭代器的__iter__()方法返回自身。
  1. 是否能够重复遍历
  • 可迭代对象通常支持多次遍历,因为每次调用iter()都会生成一个新的迭代器。
  • 迭代器只能遍历一次,因为它在内部维护了当前遍历的状态,一旦遍历完毕就无法重置。
  1. 数据消耗特性:
  • 可迭代对象中的数据元素不会在遍历中被“消耗”。
  • 迭代器中的数据元素在遍历后被“消耗”掉,不可再次访问。

可迭代对象与迭代器的关系

所有的迭代器都是可迭代对象(因为迭代器也实现了__iter__()方法),但是并不是所有的可迭代对象都是迭代器

如何自定义可迭代对象与迭代器?

自定义可迭代对象

要创建一个自定义的可迭代对象,我们需要在类中实现__iter__()方法。iter()方法应该返回一个迭代器对象。

class MyIterable:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return iter(self.data)

# 使用自定义的可迭代对象
my_iterable = MyIterable([1, 2, 3])
for item in my_iterable:
    print(item)

自定义迭代器

要创建一个自定义的迭代器,我们需要在类中实现__iter__()和__next__()方法。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):
            value = self.data[self.index]
            self.index += 1
            return value
        else:
            raise StopIteration

# 使用自定义的迭代器
my_iterator = MyIterator([1, 2, 3])
for item in my_iterator:
    print(item)

总结

  • **可迭代对象(Iterable)**是能够返回迭代器的对象,常见的序列类型(如list、tuple、str)、集合类型、字典类型都是可迭代对象。
  • **迭代器(Iterator)**是可以逐个访问元素的对象,它实现了__next__()方法和__iter__()方法。
  • 迭代器和可迭代对象的关系是:**所有迭代器都是可迭代对象,但并非所有可迭代
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立秋6789

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值