文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python iterator(迭代器)

2023-01-31 00:59

关注

迭代:重复做一件事
iterable(可迭代)对象:支持“每次仅返回自身所包含的其中一个元素”的对象
iterable对象实现了__iter__方法
    序列类型,如:list、str、tuple
    非序列类型,如:dict、file
    用户自定义的一些包含了__iter__()或__getitem__方法的类      
    用dir(object)时,只要有__iter__()方法或__getitem__方法都是iterable对象。
    object.__iter__()   每运行一次,都返回一个迭代器对象的内存地址
    例:i1=list1.__iter__()       返回一个迭代器对象
           i1.next()
           i1.next()
           ....
           
迭代器(iterator)
    迭代器又称为游标(cursor),它是程序设计的软件设计模式,是一种可在容器物件(container)上实现元素遍历的接口。
    迭代器是一种特殊的数据结构,当然在python中,它也是以对象的形式存在的。简单理解方式:对于一个集体中的每一个元素,想要执行遍历,那么针对这个集体的迭代器就定义了遍历该集体中每一个元素的顺序或方法。
    迭代器本身是不可逆的。
    可以使用一个“可迭代对象”的__iter__()方法生成一个“迭代器对象”
           In [31]: print list1
           [(1, 2), (3, 4), (5, 6)]
           In [32]: iterable1=list1.__iter__()
           In [33]: iterable1.next()
           Out[33]: (1, 2)
           In [34]: iterable1.next()
           Out[34]: (3, 4)
           In [35]: iterable1.next()
           Out[35]: (5, 6)
    也可以使用iter函数生成一个迭代器对象。用法: iter(container_object)
           In [37]: iterable1=iter(list1)
           In [38]: iterable1.next()
           Out[38]: (1, 2)
           In [39]: iterable1.next()
           Out[39]: (3, 4)
           In [40]: iterable1.next()
           Out[40]: (5, 6)

在python中,迭代器是遵循迭代协议的对象;使用iter()函数可以从任何序列对象中生成一个迭代器对象
若要使用迭代器,需要在类中定义next()方法(python3中是 __next__())
要使得迭代器指向下一个元素,则使用成员函数next() (在python3中,是函数next(),而非成员函数)
当没有元素时,则触发StopIteration异常
   
    for循环可用在任何可迭代对象:
    for循环开始时,会通过迭代协议传递给iter()内置函数,从而能够从可迭代对象中获得一个迭代器,返回的对象含有需要的next方法。
   
python的列表解析:
    根据一个已存在列表再生成另一个新列表时,可以使用列表解析功能。
    列表解析是python迭代机制的一种应用,它常用于实现创建新的列表,因此要放置于[]中。
    语法:[expression for iter_var in iterable_object]
               [expression for iter_var in iterable_object if condition_expression]

    例:
    list1=[1,2,3,4]
    list2=[ i**2 for i in list1]
    list3=[ i**2 for i in list1 if i%2==0 ]
    print list2,list3
       
    for i in [ x**2 for x in range(1,11)]: print i/2
       
    import os
    os.listdir("/path")     以指定目录中的所有文件为列表元素,返回一个新列表
    string.endswith(".suffix")  判断字符串对象是否以".suffix"为后缀,返回布尔值
   
    filelist2 = [ filename for filename in os.listdir("/var/log") if filename.endswith(".log") ]
    print filelist2
   
    list1=['x','y','z']
    list2=[1,2,3]
    list3=[ (i,j) for i in list1 for j in list2 ]       嵌套使用列表解析
    print list3
       
    list4=[ (i,j) for i in list1 for j in list2 if j%2!=0 ]
    print list4
       
    list5=range(10)
    list5=[str(i)  for i in list5] 将数字类型的列表转换成字符型的列表
       
    list6=range(10)
    list6=[str(i)+'\n'  for i in list6] 将数字类型的列表转换成字符型的列表,并在每个元素后面加上一个"\n"的字符串
    f=file('/tmp/newfile','w+')
    f.writelines(list6)
    f.close()
    ipython需要使用SQLite才支持命令历史,否则不支持

Python生成器 
    如果元素过多,列表解析就特别占用资源。使用生成器,一次只生成一个元素,节省资源。  
    生成器表达式并不真正创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来。
    生成器表达式使用了"惰性计算"或称为"延迟求值"的机制。
    序列过长,并且每次只需要猎取一个元素时,就应当考虑使用生成器表达式而不是列表解析。生成器表达式用于python2.4以后的版本
    语法: (expression for iter_var in iterable)
        (expression for iter_var in interable if condition_expression)
        例:
        generator1=( i**2 for i in range(1,11))
        generator1.next()
    当然可以使用for遍历生成器,在遍历生成器时才生成值、每次只创建一个值,生成器尽量延迟生成值。
    每次仅从函数中取yield值一次,然后记录位置,下次从本次的位置继续取值。
       
    for x in ( i**2 for i in range(1,11)): print x/2
       
    例:剖析yield运行过程
       def func1():
           yield 1
           yield 2
           yield 3
       g1=func1()
       '''print g1.next()
       print g1.next()
       print g1.next()
       '''
       for item in g1:
           print item

       例:自定义一个xxreadlines()函数,逐行读取文件的内容
       def xxreadlines(filename):
           seek=0
           while True:
               with open(filename,"r") as f:
                   f.seek(seek)
                   data=f.readline()
                   if data:
                       seek=f.tell()
                       yield data
                   else:
                       return
       g1=xxreadlines("/tmp/test1")
       print g1.next()
       print g1.next()
       说明:with在打开文件后自动close;yield可以保留函数运行过程中的状态。
       
产生偏移和元素enumerate
    range 可在非完备遍历中用于生成索引偏移,而非偏移元素。
    如果同时需要偏移索引和偏移元素,则可以使用enumerate()函数
    此内置函数返回一个生成器对象 
    例:
        In [67]: str1="www.example.com"
        In [68]: e1=enumerate(str1)
        In [69]: e1.next()      返回值既有索引,又有元素
        Out[69]: (0, 'w')
        In [70]: e1.next()
        Out[70]: (1, 'w')
        In [71]: e1.next()
        Out[71]: (2, 'w')
        In [72]: e1.next()
        Out[72]: (3, '.')
        In [73]: e1.next()
        Out[73]: (4, 'e')

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯