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

简介:

迭代:重复做一件事
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,如需转载请自行联系原作者
目录
相关文章
|
23天前
|
开发者 Python 容器
深入理解Python迭代器:迭代机制的核心与应用
本文介绍了Python迭代器的核心概念、工作原理和应用场景。迭代器是遍历容器类型数据结构(如列表、元组、字典和集合)的对象,遵循迭代器协议,具有记忆遍历位置和一次性特点。通过实现迭代器协议,开发者能为自定义类型定义迭代行为,实现高效处理大量数据和与其他迭代工具协同工作。迭代器与可迭代对象的区别在于,可迭代对象实现`__iter__()`方法,返回迭代器,而迭代器实现`__next__()`方法,用于逐个访问元素。理解并运用迭代器能提升Python代码的性能和可读性。
|
30天前
|
算法 大数据 Python
Python生成器:优雅而高效的迭代器
Python生成器:优雅而高效的迭代器
|
1月前
|
Python
请解释 Python 中的生成器的工作原理。
【2月更文挑战第20天】【2月更文挑战第58篇】请解释 Python 中的生成器的工作原理。
|
1月前
|
Python
Python如何使用生成器生成更加优雅和高效的代码
Python如何使用生成器生成更加优雅和高效的代码
23 0
|
3天前
|
大数据 数据处理 开发者
深入理解Python中的迭代器和生成器
Python中的迭代器和生成器是实现高效循环和处理大型数据集的重要工具。本文将深入探讨迭代器和生成器的概念、原理以及在实际开发中的应用场景,帮助读者更好地理解和利用这些强大的工具。
|
16天前
|
人工智能 机器人 测试技术
【Python】Python迭代器与生成器的区别(详细讲解)
【Python】Python迭代器与生成器的区别(详细讲解)
【Python】Python迭代器与生成器的区别(详细讲解)
|
1月前
|
Python
在Python中,如何创建一个迭代器?
【2月更文挑战第24天】【2月更文挑战第81篇】在Python中,如何创建一个迭代器?
|
1月前
|
Python
请解释Python中的迭代器和生成器的区别?并分别举例说明。
【2月更文挑战第24天】【2月更文挑战第80篇】请解释Python中的迭代器和生成器的区别?并分别举例说明。
|
1月前
|
算法 Java Shell
Python教程第5章 | Python迭代器和生成器
Python迭代器和生成器、综合案例
25 0
|
1月前
|
Python
如何在Python中使用生成器来生成列表?
如何在Python中使用生成器来生成列表?
11 1

热门文章

最新文章