python中的迭代器,可迭代对象(详细剖析)

一 什么是迭代?什么是迭代器?

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或者结果。每一次对过程的重复就是一次迭代,而每一次迭代得到的结果会作为下一次迭代的初始值
大白话就是重复执行同一个操作或者活动,下一次迭代的开始是上一次迭代的结束。
迭代器是一个对象,它的工作是遍历和选择序列中的对象,它提供了一种访问容器对象中各个元素而又不必暴露容器内部细节的方法
迭代器可以实现迭代操作。

二 python中的迭代器

要想了解迭代器就得知道迭代器协议,就像要想知道Web就得知道HTTP协议一样。协议是一种规则,只有满足了这些规则,你才能使用该协议衍生出来的东西。

1. python中的迭代器协议

python中的迭代器协议是指:一个对象需要提供next方法,该方法要么返回迭代对象中的下一项,要么就抛StopIteration异常,迭代终止。

2. 迭代器的实现原理

在python中,只要一个对象实现了以下两个方法,那么它就是一个迭代器
_ iter _: 返回一个可迭代对象
_ next _: 返回迭代器的下一项,当没有元素可以返回时抛StopIteration异常,迭代终止。

下面用上面的两个方法来实现一个返回斐契那波数列的迭代器,如下

from collections.abc import Iterable, Iterator

#实现一个返回斐契那波数列的迭代器
class fibo_iterator():

    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        # 由于自己就是一个迭代器,所以返回自己就行
        return self

    def __next__(self):

        if self.b > 100:
            raise StopIteration
        else:
            self.a, self.b = self.b, self.a + self.b
            return self.a
            

我们可以用collections.abc库和内置函数 isinstance() 来判断一个·对象是不是一个指定类型的对象。现在我们用它们来判断fibo_iterator是不是一个迭代器,如下

fibo = fibo_iterator()
print(type(fibo))
print("是否是可迭代对象:", isinstance(fibo, Iterable))
print("是否是迭代器:", isinstance(fibo, Iterator))
print(dir(fibo))
>>>
<class '__main__.fibo_iterator'>
是否是可迭代对象: True
是否是迭代器: True
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']

从结果可以看出,我们上面实现的 fibo 确实是一个迭代器,因为实现了__next__ 和__iter__ 方法。其中__iter__ 返回一个可迭代对象,如上结果所示。接下来看看 _ next _ 方法。

fibo = fibo_iterator()
print("第一次:", next(fibo))
print("第二次:", next(fibo))
print("第三次:", next(fibo))
print("第四次:", next(fibo))
print("第五次:", next(fibo))
>>>
第一次: 1
第二次: 1
第三次: 2
第四次: 3
第五次: 5

上面用内置函数next() 对迭代器fibo进行 迭代操作,其实是 next() 调用了迭代器里面的
看 _ next _ 方法,从而实现了迭代操作。


三 python中的可迭代对象

python中规定:凡是实现了__iter__ (或者__getitem__)方法的都是可迭代对象(Iterable),可迭代对象都可以被迭代器(Iterator)进行迭代操作。

1.可迭代对象

python中基础序列基本都是可迭代对象,我们可以用内置函数 isinstance() 来进行判断,如下

from collections.abc import Iterable, Iterator

#python的可迭代对象
ls = [1, 2, 3, 4, 5]
tu = ('a', 'b')
dic = {'a': 1, 'b': 2}
strs = 'abcd'
se = {'d', 2, 3}

print("列表是不是可迭代对象:", isinstance(ls, Iterable))
print("元组是不是可迭代对象:", isinstance(tu, Iterable))
print("字典是不是可迭代对象:", isinstance(dic, Iterable))
print("字符串是不是可迭代对象:", isinstance(strs, Iterable))
print("集合是不是可迭代对象:", isinstance(se, Iterable))
print('分割线'.center(50, '='))
print(ls.__dir__())
print(tu.__dir__())
print(dic.__dir__())
print(strs.__dir__())
print(se.__dir__())

>>>
列表是不是可迭代对象: True
元组是不是可迭代对象: True
字典是不是可迭代对象: True
字符串是不是可迭代对象: True
集合是不是可迭代对象: True
=======================分割线========================
['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__len__', '__getitem__', '__setitem__', '__delitem__', '__add__', '__mul__', '__rmul__', '__contains__', '__iadd__', '__imul__', '__new__', '__reversed__', '__sizeof__', 'clear', 'copy', 'append', 'insert', 'extend', 'pop', 'remove', 'index', 'count', 'reverse', 'sort', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__']
['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__len__', '__getitem__', '__add__', '__mul__', '__rmul__', '__contains__', '__new__', '__getnewargs__', 'index', 'count', '__doc__', '__str__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__len__', '__getitem__', '__setitem__', '__delitem__', '__contains__', '__new__', '__sizeof__', 'get', 'setdefault', 'pop', 'popitem', 'keys', 'items', 'values', 'update', 'fromkeys', 'clear', 'copy', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__']
['__repr__', '__hash__', '__str__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__mod__', '__rmod__', '__len__', '__getitem__', '__add__', '__mul__', '__rmul__', '__contains__', '__new__', 'encode', 'replace', 'split', 'rsplit', 'join', 'capitalize', 'casefold', 'title', 'center', 'count', 'expandtabs', 'find', 'partition', 'index', 'ljust', 'lower', 'lstrip', 'rfind', 'rindex', 'rjust', 'rstrip', 'rpartition', 'splitlines', 'strip', 'swapcase', 'translate', 'upper', 'startswith', 'endswith', 'isascii', 'islower', 'isupper', 'istitle', 'isspace', 'isdecimal', 'isdigit', 'isnumeric', 'isalpha', 'isalnum', 'isidentifier', 'isprintable', 'zfill', 'format', 'format_map', '__format__', 'maketrans', '__sizeof__', '__getnewargs__', '__doc__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__dir__', '__class__']
['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__sub__', '__rsub__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__isub__', '__iand__', '__ixor__', '__ior__', '__len__', '__contains__', '__new__', 'add', 'clear', 'copy', 'discard', 'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', '__reduce__', 'remove', '__sizeof__', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__']

从上面结果可知,列表,元组,字典,字符串和集合都是可迭代对象,因为它们都实现了__iter__(或者__getitem__)方法

2.可迭代对象如何被迭代?

操作层面我们对可迭代对象进行迭代取值很简单,用关键字for,如下

ls = [1, 2, 3, 4, 5]

for i in ls:
    print(i)
>>>
1
2
3
4
5

那么它(可迭代对象)是如何被迭代的呢?这就和上面的迭代器联系起来了,如下
可迭代对象如何被迭代:

  • 当对可迭代对象进行迭代(for)操作时,首先会调用内置函数iter()返回一个迭代器(Iterator)
  • 对返回的迭代器调用 next()函数,逐个读取迭代器内容
ls = [1, 2, 3, 4, 5]
#for对可迭代对象进行迭代
for i in ls:
    print(i)
    
print('分割线'.center(40, '*'))
#for原理解析
ls_iterator = iter(ls)
print(type(ls_iterator))

print(next(ls_iterator))
print(next(ls_iterator))
print(next(ls_iterator))
print(next(ls_iterator))
print(next(ls_iterator))

1
2
3
4
5
******************分割线*******************
<class 'list_iterator'>
1
2
3
4
5

可以看到,用for和用iter(),next() 对可迭代对象进行迭代取值效果是一样,因为for本来就是对iter()和next()的封装。

综上,用for对可迭代对象进行迭代的操作如下:

在这里插入图片描述
以上流程就体现了在对可迭代对象遍历取值时迭代器(Iterator)充当“工具”的作用。

3.可迭代对象和迭代器的区别

从上面来看可迭代对象与迭代器的区别就很明显了,如下:

  • 在实现上的不同可迭代对象只要实现__iter__方法就行,而迭代器要实现__iter__和__next__方法,最大区别就是__next__方法。
  • 作用上的不同可迭代对象一般是一些序列,文件等,而迭代器则是提供了一种对可迭代对象进行迭代取值的工具。

4.思考:迭代器为什么要是可迭代的(Iterable)?

思考:迭代器为什么是可迭代对象(Iterable)?提示:next()



以上就是本人对python迭代器的一些思考和拙见,如有误,还望指出。如有帮助,点个赞。

  • 38
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Python迭代器可以是无限的循环。这意味着迭代器对象可以无限地生成下一个元素,而不会停止。一个常见的例子是使用itertools模块的`cycle`函数来创建一个无限迭代器。这个函数接受一个可迭代对象作为参数,并在迭代过程不断重复这个对象的元素。 以下是一个示例代码,展示了如何使用`cycle`函数创建一个无限循环的迭代器: ``` import itertools l = ['Geeks', 'for', 'Geeks'] iterators = itertools.cycle(l) for i in range(6): print(next(iterators), end=" ") ``` 输出结果为:`Geeks for Geeks Geeks for Geeks Geeks` 在这个例子,我们定义了一个列表`l`,然后使用`cycle`函数创建了一个无限迭代器`iterators`。在循环,我们使用`next`函数来获取迭代器的下一个元素,并将其打印出来。由于迭代器是无限的,所以它会无限地重复打印列表的元素。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python 教程之控制流(11)无限迭代器](https://blog.csdn.net/m0_73720982/article/details/127122759)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Python迭代器定义与简单用法分析](https://download.csdn.net/download/weixin_38689551/13772081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值