zoukankan      html  css  js  c++  java
  • python迭代器与iter()函数实例教程

    python迭代器与iter()函数实例教程

    发布时间:2014-07-16编辑:脚本学堂
    本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程序员迭代非序列类型,包括用户定义的对象。
     

    迭代器是在版本 2.2 被加入 Python 的,它为类序列对象提供了一个类序列的接口。
    序列是一组数据结构,你可以利用它们的索引从0 开始一直“迭代“ 到序列的最后一个条目。
    用“计数“的方法迭代序列是很简单的。
    Python 的迭代无缝地支持序列对象,而且它还允许程序员迭代非序列类型,包括用户定义的对象。

    迭代器用起来很灵巧,可以迭代不是序列但表现出序列行为的对象,例如字典的 key,一个文件的行等。
    当使用循环迭代一个对象条目时,几乎不可能分辨出它是迭代器还是序列。不必去关注这些,因为 Python 让它象一个序列那样操作。

    如何迭代?

    迭代器就是有一个 next() 方法的对象,而不是通过索引来计数。当你或是一个循环机制(例如 for 语句)需要下一个项时,调用迭代器的 next() 方法就可以获得它。条目全部取出后,会引发一个 StopIteration 异常,这并不表示错误发生,只是告诉外部调用者,迭代完成.

    不过,迭代器也有一些限制。例如你不能向后移动,不能回到开始,也不能复制一个迭代器.如果你要再次(或者是同时)迭代同个对象,你只能去创建另一个迭代器对象。不过,这并不糟糕,因为还有其他的工具来帮助你使用迭代器。(www.jbxue.com 脚本学堂 整理)

    reversed() 内建函数将返回一个反序访问的迭代器。enumerate() 内建函数同样也返回迭代器.另外两个新的内建函数,any() 和 all() ,在 Python 2.5 中新增,如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真。本章先前部分展示了如何在 for 循环中通过索引或是可迭代对象来遍历条目。同时 Python 还提供了一整个 itertools 模块,它包含各种有用的迭代器.

    一,使用迭代器

    ===序列===

    正如先前提到的,迭代 Python 的序列对象和你想像的一样:
     

    复制代码代码示例:
    >>> myTuple = (123,‘xyz’,45.67)
    >>> i = iter(myTuple)
    >>> i.next()
    123
    >>> i.next()
    ‘xyz’
    >>> i.next()
    45.67
    >>> i.next()
    Traceback (most recent call last):
    File “<stdin>”,line 1,in <module>
    StopIteration
     

    如果这是一个实际应用程序,那么需要把代码放在一个 try-except 块中。序列现在会自动地产生它们自己的迭代器,所以一个 for 循环: 
     

    复制代码代码示例:
    for i in seq:
        do_something_to(i)

    实际工作方式:
     

    复制代码代码示例:
    fetch = iter(seq)
    while True:
    try:
    i = fetch.next()
    except StopIteration:
    break
    do_something_to(i)
     

    不过不需要改动你的代码,因为 for 循环会自动调用迭代器的 next() 方法(以及监视StopIteration 异常)。

    ===字典===

    字典和文件是另外两个可迭代的 Python 数据类型。字典的迭代器会遍历它的键(keys).
    语句 for eachKey in myDict.keys() 可以缩写为 for eachKey in myDict ,例如:
     

    复制代码代码示例:
    >>> legends = { (‘Poe’,‘author’): (1809,1849,1976),
    … (‘Gaudi’,‘architect’): (1852,1906,1987),
    … (‘Freud’,‘psychoanalyst’): (1856,1939,1990)
    … }

    >>> for eachLegend in legends:
    … print ‘Name: %stOccupation: %s‘ % eachLegend
    … print ‘ Birth: %stDeath: %stAlbum: %sn‘
    … % legends[eachLegend]

    Name: Freud Occupation: psychoanalyst
    Birth: 1856 Death: 1939 Album: 1990
    Name: Poe Occupation: author
    Birth: 1809 Death: 1849 Album: 1976
    Name: Gaudi Occupation: architect
    Birth: 1852 Death: 1906 Album: 1987

    另外,Python 还引进了三个新的内建字典方法来定义迭代:
    myDict.iterkeys() (通过 keys 迭代),myDict.itervalues() (通过 values 迭代),以及 myDicit.iteritems() (通过 key/value 对来迭代)。(www.jbxue.com 脚本学堂 整理)

    注意,in操作符也可以用于检查字典的 key 是否存在,之前的布尔表达式myDict.has_key(anyKey) 可以被简写为 anyKey in myDict。

    ===文件===

    文件对象生成的迭代器会自动调用 readline() 方法。
    这样循环就可以访问文本文件的所有行。程序员可以使用 更简单的 for eachLine in myFile 替换 for eachLine in myFile.readlines():
     

    复制代码代码示例:
    >>>myFile=open(‘config-win.txt’)
     
    >>> for eachLine in myFile:
    … print eachLine,# comma suppresses extra n

    [EditorWindow]
    font-name: courier new
    font-size: 10
    >>> myFile.close()

    二,可变对象和迭代器

    记住,在迭代可变对象的时候修改它们并不是个好主意。这在迭代器出现之前就是一个问题。
    一个流行的例子就是循环列表的时候删除满足(或不满足)特定条件的项:
     

    复制代码代码示例:
    for eachURL in allURLs:
        if not eachURL.startswith(‘http://’):
            allURLs.remove(eachURL) # YIKES!!
     

    除列表外的其他序列都是不可变的,所以危险就发生在这里。一个序列的迭代器只是记录你当前到达第多少个元素,所以如果你在迭代时改变了元素,更新会立即反映到你所迭代的条目上.在迭代字典的 key 时,你绝对不能改变这个字典。使用字典的 keys() 方法是可以的,因为keys() 返回一个独立于字典的列表。而迭代器是与实际对象绑定在一起的,它将不会继续执行下去:
     

    复制代码代码示例:
    >>> myDict = {‘a’: 1,‘b’: 2,‘c’: 3,‘d’: 4}
    >>> for eachKey in myDict:
    … print eachKey,myDict[eachKey]
    … del myDict[eachKey]
    … a 1
    Traceback (most recent call last):
    File “<stdin>”,line 1,in <module>
    RuntimeError: dictionary changed size during iteration
     

    这样可以避免有缺陷的代码。更多有关迭代器的细节请参阅 PEP 234 .

    三,如何创建迭代器

    对一个对象调用 iter() 就可以得到它的迭代器。它的语法如下:
    iter(obj)
    iter(func,sentinel)
    如果传递一个参数给 iter() ,它会检查你传递的是不是一个序列,如果是,那么很简单: 
    根据索引从 0 一直迭代到序列结束。另一个创建迭代器的方法是使用类,将在第 13 章详细介绍,一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用.
    如果是传递两个参数给 iter() ,它会重复地调用 func ,直到迭代器的下个值等于sentinel。

     
     
     
  • 相关阅读:
    根据EsLint配置WebStorm格式化代码风格
    Vue中使用vant-UI实现移动端自定义省市区三级联动
    Vue中使用Element-UI实现表格跨页多选
    Vue中使用iview-UI实现切换Tab页网络请求优化
    Vue中使用iview-UI按需引入Select组件下拉框无法生效问题
    Vue中使用iview-UI表格样式修改和使用自定义模板数据渲染相关
    Vue中使用Element-UI表单验证相关问题及解决
    Vue 3.0 多页面项目之商家平台练习
    五 创建道路模型(2 道路的挖填方量计算及条件部件)
    五 创建道路模型(1 道路三要素)
  • 原文地址:https://www.cnblogs.com/z-books/p/5316947.html
Copyright © 2011-2022 走看看