python iterator(迭代器) and generator(生成器)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介:

迭代:重复做一件事
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')










本文转自 meteor_hy 51CTO博客,原文链接:http://blog.51cto.com/caiyuanji/1833959,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
存储 索引 Python
|
2月前
|
Python
Python生成器、装饰器、异常
【10月更文挑战第15天】
|
2月前
|
传感器 大数据 数据处理
深入理解Python中的生成器:用法及应用场景
【10月更文挑战第7天】深入理解Python中的生成器:用法及应用场景
52 1
|
2月前
|
存储 数据处理 Python
深入解析Python中的生成器:效率与性能的双重提升
生成器不仅是Python中的一个高级特性,它们是构建高效、内存友好型应用程序的基石。本文将深入探讨生成器的内部机制,揭示它们如何通过惰性计算和迭代器协议提高数据处理的效率。
|
1月前
|
存储 程序员 数据处理
深入理解Python中的生成器与迭代器###
本文将探讨Python中生成器与迭代器的核心概念,通过对比分析二者的异同,结合具体代码示例,揭示它们在提高程序效率、优化内存使用方面的独特优势。生成器作为迭代器的一种特殊形式,其惰性求值的特性使其在处理大数据流时表现尤为出色。掌握生成器与迭代器的灵活运用,对于提升Python编程技能及解决复杂问题具有重要意义。 ###
|
2月前
|
存储 大数据 数据处理
Python 中的列表推导式与生成器:特性、用途与区别
Python 中的列表推导式与生成器:特性、用途与区别
27 2
|
2月前
|
存储 大数据 数据处理
理解Python中的生成器:高效迭代的秘密
【10月更文挑战第8天】理解Python中的生成器:高效迭代的秘密
40 0
|
2月前
|
存储 大数据 程序员
深入理解Python中的生成器
【10月更文挑战第8天】深入理解Python中的生成器
18 0
|
2月前
|
存储 大数据 Python
Python 中迭代器与生成器:深度解析与实用指南
Python 中迭代器与生成器:深度解析与实用指南
19 0
|
7月前
|
Python
【Python操作基础】——字典,迭代器和生成器
【Python操作基础】——字典,迭代器和生成器