首页 > 编程语言 >python-迭代器

python-迭代器

时间:2022-11-19 17:12:07浏览次数:45  
标签:__ iterator 迭代 python self iter actions

 

迭代的概念

使用for循环遍历取值的过程叫做迭代,比如:使用for循环遍历列表获取值的过程

# Python 中的迭代
for value in [2, 3, 4]:
    print(value)
复制代码

1.2 可迭代对象

标准概念:在类里面定义__iter__方法,并使用该类创建的对象就是可迭代对象

简单记忆:使用for循环遍历取值的对象叫做可迭代对象, 比如:列表、元组、字典、集合、range、字符串


 
# 常见的可迭代对象
iterables = [
    "123",          # 字符串
    [1,2,3],        # 列表
    (1,2,3),        # 元组
    {1:'a',2:'b'},  # 字典
    {1,2,3}         # 集合
]

 

可迭代对象之间共同的特点

利用python的内省能力 使用dir()函数获取python对象的属性 

# 常见的可迭代对象
iterables = [
    "123",          # 字符串
    [1,2,3],        # 列表
    (1,2,3),        # 元组
    {1:'a',2:'b'},  # 字典
    {1,2,3}         # 集合
]

# for iterable in iterables:
#     print(type(iterable))
#     for x in iterable:
#         print(x,end=',')
#     print('')


def common_attrs(*objs):
    """
    计算对象之间的共同属性
    :param objs:
    :return:
    """
    assert  len(objs) >0
    attrs = set(dir(objs[0]))
    for obj in objs[1:]:
        print(obj)
        attrs &= set(dir(obj))  # 取交集
    attrs -= set(dir(object))   # 剔除基础对象的属性
    return attrs

iterable_common_attrs=common_attrs(*iterables)
print(iterable_common_attrs)

 输出结果如下

[1, 2, 3]
(1, 2, 3)
{1: 'a', 2: 'b'}
{1, 2, 3}
{'__contains__', '__iter__', '__len__'}

因为上面都是容器类型的可迭代对象,所以有长度 和是否包含属性

在加入文件类型的可以

f = open('D:\\PycharmProject\\StudentSenior\\file\\demo1.xlsx','r')

# d=common_attrs(f)

iterable_common_attrs &= set(dir(f))
print(iterable_common_attrs)

输出结果如下

{'__iter__'}

现在我们得到可迭代对象的一个唯一接口 __iter__

这种双下划线的__iter__ 方法 我们需要用相应的内置函数去调用 iter()

for iterable in iterables:
    print(iter(iterable))

输出如下

<str_iterator object at 0x00000184F4C81F70>
<list_iterator object at 0x00000184F4C81F70>
<tuple_iterator object at 0x00000184F4C81F70>
<dict_keyiterator object at 0x00000184F4B76400>
<set_iterator object at 0x00000184F4B13940>
<_io.TextIOWrapper name='D:\\PycharmProject\\StudentSenior\\file\\demo1.xlsx' mode='r' encoding='cp936'>

我们会 发现生成了iterator object对象,这也是 迭代器

 

 

迭代器共同的属性

# 由可迭代对象列表得到相应的迭代器列表
iterator = [iter(iterable) for iterable in iterables]

# 计算迭代器的共同属性
iterator_common_attrs = common_attrs(*iterator)

print(iterator_common_attrs)

输入结果如下

{'__iter__', '__next__'}

证明迭代器有两个接口 __iter__  和 __next__

 

 

对一个迭代器迭代

actions = ['点赞','投币','收藏']  # 可迭代对象

actions_iterator = iter(actions)   # 构建迭代器

while 1:
    action = next(actions_iterator)  # 运行三次
    print(action)

结果如下:

Traceback (most recent call last):
  File "D:\PycharmProject\StudentSenior\test_openpyxl\test05.py", line 8, in <module>
    action = next(actions_iterator)  # 运行三次
StopIteration
点赞
投币
收藏

 我们可以发现 在迭代完最后一个元素后在去迭代 发生了一个异常StopIteration,也就是迭代终止的意思

至此我们已经知道了迭代的三个关键步骤:

  调用iter(iterable)来构建迭代器

  (多次)调用next(iterator)来获取值

  最后捕获StopIteration异常来判断迭代结束

改进如下

# 用while 循环模拟for循环迭代
# 创建迭代器
iterator = iter(actions)   # 对应 可迭代对象的__iterator__ 方法
while 1:
    try:
        # 通过迭代器获取下一个对象
        print(next(iterator))  # 对应迭代器的 __next__ 方法
    except StopIteration:      # 捕获异常来判断结束
        # 迭代结束
        break

 

迭代器的 __iter__ 方法作用在哪里呢?

 

自定义一个迭代器

迭代器的的基本功能:

  初始化时要传入可迭代对象,这样才能知道去那取数据

  要初始化迭代进度

  每次迭代时,即每次调用__next__() 方法时:

    如果仍有元素可供迭代,则返回本轮迭代的元素,同时更新当前迭代进度

    如果已无元素可供返回,则迭代结束,抛出StopIteration异常 

再添加一点额外的逻辑:

  设置一个黑名单,如果当前元素在黑名单内,则跳过

  将某些符合条件的数据*2之后再返回


BLACK_LIST = ['白嫖','取关']


class SuzhiIterator:

    def __init__(self,actions):
        self.actions =actions
        self.index = 0                   # 初始化索引下标


    def __next__(self):

        while self.index < len(self.actions):
            action = self.actions[self.index]
            self.index +=1
            if action in BLACK_LIST:
                continue
            elif '币' in action:
                return action*2
            else:
                return action
        raise StopIteration


actions = ['点赞','投币','取关']
sz_iterator = SuzhiIterator(actions)

while True:
    try:
        print(next(sz_iterator))
    except StopIteration:
        break
        

这个可以放在while 循环里面去 迭代,但是不能放在for 循环去迭代,

会报 是一个不可迭代对象

TypeError: 'SuzhiIterator' object is not iterable

那这时候我们可能想到要不要额外定义一个类 去实现__iter__

# 一个没有存在意义的可迭代对象
class SuzhiActions:

    def __init__(self,actions):
        self.actions = actions

    def __iter__(self):
        return SuzhiIterator(self.actions)

for i in SuzhiActions(actions):
    print(i)

我们这样做太过于冗余

我们正确的做法是让迭代器自己实现

class SuzhiIterator:

    def __init__(self,actions):
        self.actions =actions
        self.index = 0                   # 初始化索引下标


    def __next__(self):

        while self.index < len(self.actions):
            action = self.actions[self.index]
            self.index +=1
            if action in BLACK_LIST:
                continue
            elif '币' in action:
                return action*2
            else:
                return action
        raise StopIteration
    
    def __iter__(self):
        return self

在这里 __iter__ 接口的含义就是要返回一个迭代器,那现在__iter__ 已经在这个迭代器里面了,而他这个对象自己就是一个迭代器,所以返回这个对象就可以了

迭代器协议

在python文档中明确指出了,迭代器必须同时实现 __next__ 和 __iter__ 两个方法,这称之为 迭代器协议

根据这个协议,迭代器必须是可迭代的,换言之,迭代器 是一种 可迭代对象

缺少了 __iter__ 方法的迭代器是不完整的,不符合迭代器协议的要求

所有迭代器的 __iter__ 方法都只要千篇一律的return shlf 即可

 

 

标签:__,iterator,迭代,python,self,iter,actions
From: https://www.cnblogs.com/niunai/p/16906498.html

相关文章

  • 【mysql】关于python建立mysql相关操作
    1.安装用pip安装指令pipinstallpymysql查看安装成功#cmdpipshowmysql#cmd找list中有该软件piplist#python中不报错importpymysql2.操作流程3.封装......
  • 深度学习与通信交叉领域的python包:deepcom
    什么是deepcom在进行深度学习与通信领域的交叉研究时,有一些反复使用的算法与训练流程。但是现有的学习框架主要集中在网络的训练部分,对于通信领域的参数压缩与高效传输并......
  • Python学习笔记(三)
    运算符和表达式算术运算python在这里直接支持了幂运算,c的话需要额外的头文件导入此外,python也是支持取模%和取整运算的。The / (division)and // (floordivisi......
  • 二叉树的前、中、后序遍历(迭代版)
    //前序遍历顺序:中-左-右,入栈顺序:中-右-左classSolution{publicList<Integer>preorderTraversal(TreeNoderoot){List<Integer>result=newArrayL......
  • Python的线程如何理解
    Num01-->多线程threadingPython中建议使用threading模块,而不要使用thread模块。原因如下:1,Python中threading模块对thread进行了一些包装,可以更加方便的使用。2,Python......
  • python3标准库
    本文出处 http://www.cnblogs.com/vamei   作者:Vamei序列(sequence)序列包含有定值表(tuple)和表(list)。字符串(string)是一种特殊的定值表下面的内建函数(buil......
  • python 协程学习笔记
    yield生成器frominspectimportgetgeneratorstatedefgen1():x=yield2print(x)y=yieldxreturnyg=gen1()print(getgeneratorstate(......
  • python第五章pta习题总结
    四、编程部分1、sorted函数:sorted(iterable,cmp=None,key=None,reverse=False)#iterable:可迭代的对象#cmp:比较规则#key:用来进行比较的对象,只有一个参数2、eval()......
  • 【Python小随笔】本周一、上周一、上周末日期
    importdatetime#当前日期deftoday_date():returndatetime.datetime.now().date()#上周一deflast_monday():returnstr(datetime.datetime.now()......
  • Java——集合——Collection集合——Iterator接口介绍&迭代器的代码实现&迭代器的实现
                                                       ......