【问题标题】:How do I use __getitem__ and __iter__ and return values from a dictionary?如何使用 __getitem__ 和 __iter__ 并从字典中返回值?
【发布时间】:2009-11-23 00:35:14
【问题描述】:

我有一个带有字典的对象,我想通过 __getitem__ 访问并迭代(仅值,键无关紧要)但不知道该怎么做。

例如:

Python 2.5.2 (r252:60911, Jul 22 2009, 15:33:10) 
>>> class Library(object):
...   def __init__(self):
...     self.books = { 'title' : object, 'title2' : object, 'title3' : object, }
...   def __getitem__(self, i):
...     return self.books[i]
... 
>>> library = Library()
>>> library['title']
<type 'object'>
>>> for book in library:
...   print book
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __getitem__
KeyError: 0
>>> 

我如何告诉它为字典中的每个项目简单地返回object(键无关紧要)?

【问题讨论】:

    标签: python iterator


    【解决方案1】:
    def __iter__(self): return self.books.itervalues()
    

    【讨论】:

    • 谢谢 - 我知道这很容易,但最难追踪它!欣赏它。
    • return self.books.itervalues()return iter(self.books.values()) 好吗?我认为这是一种特定于字典的便捷方法,并且惊讶地发现它返回一个dictionary-valueiterator 对象,而另一个返回一个listiterator。但是,最终结果相同。
    【解决方案2】:

    将此方法添加到库中:

    def __iter__(self):
      return self.books.itervalues()
    

    这将迭代委托给 dict,它有一个简单的方法来迭代值。阅读迭代器协议,它由__iter__(在所有可迭代对象上)和next(3.x 中的__next__)(仅在迭代器上)方法组成。

    【讨论】:

      【解决方案3】:

      你可以从你的内部数据中返回一个迭代器:

      class Library (object):
        ...
        def __iter__(self):
          return self.books.itervalues()
      

      itervalues() 返回一个指向字典值的迭代器。

      如果你想要更多的控制,你可以让__iter__成为一个生成器函数

      class Library (object):
        ...
        def __iter__(self):
          for title in self.books:
            yield self.books[title]
      

      在这种情况下,此生成器产生的结果与第一个示例中的迭代器完全相同。

      【讨论】:

        【解决方案4】:
        >>> class Library(object):
        ...     def __init__(self):                                                     
        ...             self.books = { 'title' : object, 'title2' : object, 'title3' : object, }
        ...     def __getitem__(self, i):
        ...             return self.books[i]
        ...     def __iter__(self):
        ...             return self.books.itervalues()
        ... 
        >>> library = Library()
        >>> library['title']
        <type 'object'>
        >>> for book in library:
        ...     print book
        ... 
        <type 'object'>
        <type 'object'>
        <type 'object'>
        

        【讨论】:

          【解决方案5】:

          __getitem__(self,key),其中 key 是一个整数,因为你的 self.books 是一个字典,你不能这样做 self.books[integer]

          例如:

          >>>d = {'a':'sdsdsd','b':'sfsdsd'}
          >>d[0]
          
          d[0]
          Traceback (most recent call last):
            File "<console>", line 1, in <module>
          KeyError: 0
          

          迭代协议是这样的:

          迭代器协议由两种方法组成。 __iter__() 方法必须返回迭代器对象,next() 方法返回序列中的下一个元素。 以前当 __iter__ 方法未定义时,它会通过连续调用 __getitem__ 并增加值,直到它给出索引超出范围错误,从而回退到 __getitem__

          【讨论】:

            猜你喜欢
            • 2013-12-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多