【问题标题】:make data struct iterable in python在python中使数据结构可迭代
【发布时间】:2011-03-15 12:21:27
【问题描述】:

所以我在网上做了一些查找并通过文档,但我很难找到如何做到这一点。我正在开发一款冒险游戏。我有一个级别类(其中包含一堆房间)和一个 Room 类。我希望能够执行以下操作。

l = Level()
for room in l:
    #following code here

这对我来说似乎很简单,但是我找不到实现自定义迭代器的正确过程。这可能是一个简单的答案,但我无法在网上找到它。非常感谢任何帮助!

【问题讨论】:

    标签: python loops iterator for-loop


    【解决方案1】:

    为什么不使用生成器。

    >>> import timeit
    >>> class Test:
        def __iter__(self):
            for i in range(10):
                yield i
    
    >>> t1 = lambda: [k for k in Test()]
    >>> timeit.timeit(t1)
    3.529460948082189
    
    
    >>> def test2():
        for i in range(10):
            yield i
    
    >>> t2 = lambda: [k for k in test2()]
    >>> timeit.timeit(t2)
    3.171831107365392
    

    【讨论】:

      【解决方案2】:

      作为编写生成器的替代方法,__iter__ 方法只需要返回一个迭代器 - 如果您的 Level 对象具有保存房间的内部数据结构,那么您可以直接返回它的迭代器:

      class Level(object):
          def __init__(self):
              self.rooms = []
      
          def __iter__(self):
              return iter(self.rooms)
      

      如果房间容器是字典,例如将房间名称映射到 Room 对象,然后您可以使用 dict.itervalues 方法获取 Room 对象的迭代器:

      class Level(object):
          def __init__(self):
              self.rooms = {}
      
          def __iter__(self):
              return self.rooms.itervalues()
      

      【讨论】:

        【解决方案3】:

        __iter__ 与迭代器生成器一起使用。例如

        def __iter__(self):
          for r in rooms:
            yield r
        

        迭代器生成器基本上是一种用于实现迭代器的伪方法。请注意,生成器不要求使用 for 循环。它可以根据需要使用任何构造组合(if、for、while 等)。基本上,您只需要记住调用者将按照您“调用”yield 的顺序获取元素,并且迭代将在方法执行时结束。

        请参阅 Python 教程的 this section

        【讨论】:

        • 我对这个答案的问题(另一个答案也是如此,但不是这样)实际上是你从来没有解释过这使得类实例 iterables,而不是 iterators。事实上,您似乎真的混淆了这个问题,不经意的读者可能会认为这会使实例成为迭代器。
        • @Devin,我不确定您认为我的答案的哪一部分不准确。我从来没有说过 Level 本身就是一个迭代器,我认为 OP 已经知道其中的区别。正如我所说,给定的代码用于实现迭代器。调用__iter__ 时会返回一个实际的迭代器实例
        • 我从来没有说过它不准确,只是它令人困惑。我不确定 OP 是否真的知道其中的区别,因为他显然对 Python 中的迭代器几乎一无所知。细微的术语区别也随之而来。令人困惑的帖子可能会损害对迭代器和可迭代对象的整体理解。
        【解决方案4】:

        如果您定义一个名为__iter__(self) 的成员方法,Python 将知道如何遍历它。

        在这个方法中,我建议你使用yield来返回你的数据(这叫做生成器)。您也可以返回一个列表或元组,但这在内存方面更有效。这是一个例子:

        class Test(object):
            def __iter__(self):
                for x in range(10): 
                    yield x
        
        l = Test()
        for room in l:
            print room
        

        【讨论】:

          猜你喜欢
          • 2016-12-25
          • 1970-01-01
          • 1970-01-01
          • 2021-03-01
          • 2020-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多