如何实现dictionary对象的“next”使其可读取?

2024-05-28 18:34:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典的包装纸:

class MyDict:
    def __init__(self):
        self.container = {}

    def __setitem__(self, key, value):
        self.container[key] = value

    def __getitem__(self, key):
        return self.container[key]

    def __iter__(self):
        return self

    def next(self):
        pass

dic = MyDict()
dic['a'] = 1
dic['b'] = 2

for key in dic:
    print key

我的问题是我不知道如何实现next方法来使MyDict成为可读取的。如有任何建议,将不胜感激。在


Tags: keyselfreturn字典initvaluecontainerdef
2条回答

例如,如果您希望能够在嵌套循环中使用dict-like对象,或者需要对同一对象进行多次迭代的任何其他应用程序,那么您需要实现一个返回新创建的迭代器对象的__iter__方法。在

Python的iterable对象都是这样做的:

>>> [1, 2, 3].__iter__()
<listiterator object at 0x7f67146e53d0>
>>> iter([1, 2, 3]) # A simpler equivalent
<listiterator object at 0x7f67146e5390>

对象的__iter__方法最简单的方法是在底层dict上返回迭代器,如下所示:

^{pr2}$

有关比您可能需要的更多详细信息,请参见this Github repository。在

字典本身不是迭代器(只能在上迭代一次)。您通常使它们成为一个iterable,一个可以为其生成多个迭代器的对象。在

完全删除next方法,并让__iter__在每次调用它时返回一个iterable对象。这很简单,只需返回self.container的迭代器:

def __iter__(self):
    return iter(self.container)

如果你必须让你的类成为一个迭代器,那么你必须以某种方式跟踪当前的迭代位置,并在到达“end”后提升StopIteration。一个简单的实现可以是在第一次调用__iter__时将iter(self.container)对象存储在self上:

^{pr2}$

此时,iter(self.container)对象负责跟踪迭代位置,并在到达终点时引发StopIteration。如果底层字典被更改(添加或删除键)并且迭代顺序被破坏,那么它也会引发异常。在

另一种方法是每次只在整数位置存储并索引到list(self.container),而忽略插入或删除会改变字典的迭代顺序这一事实:

_iter_index = 0

def __iter__(self):
    return self

def next(self):
    idx = self._iter_index
    if idx is None or idx >= len(self.container):
        # once we reach the end, all iteration is done, end of.
        self._iter_index = None
        raise StopIteration()
    value = list(self.container)[idx]
    self._iter_index = idx + 1
    return value

在这两种情况下,您的对象都是一个迭代器,只能在上迭代一次。一旦到达终点,就不能再重新启动。在

相关问题 更多 >

    热门问题