如何实施“下一步”字典对象是可迭代的? [英] How to implement "next" for a dictionary object to be iterable?

查看:299
本文介绍了如何实施“下一步”字典对象是可迭代的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字典的以下包装器:

I've got the following wrapper for a dictionary:

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 可迭代。任何意见,将不胜感激。

My problem is that I don't know how to implement the next method to make MyDict iterable. Any advice would be appreciated.

推荐答案

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

Dictionaries are themselves not an iterator (which can only be iterated over once). You usually make them an iterable, an object for which you can produce multiple iterators instead.

删除 next 方法,并且每次调用时都有 __ iter __ 返回一个可迭代对象。这可以简单到只返回的迭代器self.container

Drop the next method altogether, and have __iter__ return an iterable object each time it is called. That can be as simple as just returning an iterator for self.container:

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

如果你必须使你的类成为迭代器,一旦你到达'end',你必须以某种方式跟踪当前的迭代位置并提高 StopIteration 。一个天真的实现可能是第一次在 self 上存储 iter(self.container)对象 __ iter __ 被调用:

If you must make your class an iterator, you'll have to somehow track a current iteration position and raise StopIteration once you reach the 'end'. A naive implementation could be to store the iter(self.container) object on self the first time __iter__ is called:

def __iter__(self):
    return self

def next(self):
    if not hasattr(self, '_iter'):
        self._iter = iter(self.container)
    return next(self._iter)

此时 iter(self.container) object负责跟踪迭代位置,并在达到结束时引发 StopIteration 。如果基础字典被更改(已添加或删除了密钥)并且迭代顺序已被破坏,它也会引发异常。

at which point the iter(self.container) object takes care of tracking iteration position for you, and will raise StopIteration when the end is reached. It'll also raise an exception if the underlying dictionary was altered (had keys added or deleted) and iteration order has been broken.

另一种方法是执行此操作只是存储在整数位置并且每次都将索引存入列表(self.container),并且只是忽略插入或删除可以改变字典的迭代顺序这一事实:

Another way to do this would be to just store in integer position and index into list(self.container) each time, and simply ignore the fact that insertion or deletion can alter the iteration order of a dictionary:

_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

在这两种情况下,你的对象都是一个只能迭代的迭代器 一旦。到达最后,您无法再次重新启动。

In both cases your object is then an iterator that can only be iterated over once. Once you reach the end, you can't restart it again.

这篇关于如何实施“下一步”字典对象是可迭代的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆