• Python从入门到放弃之迭代器


    迭代器是Python2.1中新加入的接口(PEP 234),说明如下:

    The iterator provides a 'get next value' operation that
    produces the next item in the sequence each time it is called, raising an exception when no more items are available.
    

    说到迭代器,就不得不提迭代器对象(Iterator)和可迭代对象(Iterable)。
    接下来将分别介绍这两种对象。

    可迭代对象

    可迭代对象(Iterable)可以是任何对象,只要该对象拥有__iter__方法。该方法会返回一个迭代对象(Iterator)。
    我们常用到的如listtupledictsetstr等都是Iterable

    接下来用list做一些验证。

    #!/usr/bin/env python2.7
    """之后所有代码只保留必要部分"""
    from collections import Iterator, Iterable
    
    hasattr([], '__iter__')      # True
    isinstance([], Iterable)     # True
    type(iter([]))               # <type 'list_iterator'>
    

    注: iter()是内建方法,可将Iterable转为Iterator
    iter()只接受Iterable对象作为参数,如果不是则会抛出TypeError错误。

    可以看出,list拥有__iter__方法, 它是一个可迭代对象,当对list使用iter()方法后,会返回一个Iterator对象。

    a = [1, 2, 3, 4]
    for i in a:
        print i
    
    # 实际上内部执行
    _iter = iter(a)
    while True:
        try:
            a = _iter.next()
            print a
        except StopIteration:
            break
    

    迭代器对象

    迭代器对象则是在可迭代对象的基础上多实现一个next()方法。

    class Too(object):
        def __init__(self):
            self.n = 5
    
        def __iter__(self):
            return self
    
        def next(self):
            if self.n < 1:
                self.n = 5
                raise StopIteration
            val = self.n
            self.n -= 1
            return val
    
    t = Too(5)
    
    isinstance(t, Iterable)      # True
    isinstance(t, Iterator)      # True
    
    next(t)                      # 5
    next(t)                      # 4
    next(t)                      # 3
    next(t)                      # 2
    next(t)                      # 1
    next(t)                      # StopIteration
    

    如上则是实现一个简单的迭代器。

    可以看出,只有当使用next()方法时,迭代器才会返回一个值,而且每次返回的都是与之前一次相对应的值,如第一次返回的是5,第二次返回的是4,而不是3或者2或者别的什么数字。

    这是因为迭代器内部有一种类似状态机的机制,会保存每次的next()调用后的状态,所以每次调用总会返回正确的结果。

    总结

    迭代器对象与可迭代对象的关系总结起来就是一句话,迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象。

    参考文章:
    StackOverflow
    nvie.com
    generators-uk

  • 相关阅读:
    EasyUI--Alert()
    asp.net 页面之间传值的几种方式
    c# 的类成员
    c# protected public private internal
    C#中的多态性
    c# 静态成员和实例成员的区别
    js确认框confirm()用法实例详解
    JS中的switch case
    分分钟用上C#中的委托和事件
    Asp.net MVC中关于@Html标签Label、Editor使用
  • 原文地址:https://www.cnblogs.com/agnewee/p/6188011.html
Copyright © 2020-2023  润新知