您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

允许在迭代期间删除的自定义字典

允许在迭代期间删除的自定义字典

如您所述,您可以将要删除的项目存储在某处,并将其删除推迟到以后。然后,问题就变成了 何时 清除它们以及 如何 确保最终调用清除方法。答案是上下文管理器,它也是的子类dict

class dd_dict(dict):    # the dd is for "deferred delete"
    _deletes = None
    def __delitem__(self, key):
        if key not in self:
            raise KeyError(str(key))
        dict.__delitem__(self, key) if self._deletes is None else self._deletes.add(key)
    def __enter__(self):
        self._deletes = set()
    def __exit__(self, type, value, tb):
        for key in self._deletes:
            try:
                dict.__delitem__(self, key)
            except KeyError:
                pass
        self._deletes = None

用法

# make the dict and do whatever to it
ddd = dd_dict(a=1, b=2, c=3)

# Now iterate over it, deferring deletes
with ddd:
    for k, v in ddd.iteritems():
        if k is "a":
            del ddd[k]
            print ddd     # shows that "a" is still there

print ddd                 # shows that "a" has been deleted

with当然,如果您不处于阻塞状态,则立即删除。因为这是一个dict子类,所以它就像dict上下文管理器外部的常规对象一样工作。

您还可以将其实现为字典的包装类:

class deferring_delete(object):
    def __init__(self, d):
        self._dict = d
    def __enter__(self):
        self._deletes = set()
        return self
    def __exit__(self, type, value, tb):
        for key in self._deletes:
            try:
                del self._dict[key]
            except KeyError:
                pass
        del self._deletes
    def __delitem__(self, key):
        if key not in self._dict:
            raise KeyError(str(key))
        self._deletes.add(key)

d = dict(a=1, b=2, c=3)

with deferring_delete(d) as dd:
    for k, v in d.iteritems():
        if k is "a":
            del dd[k]    # delete through wrapper

print d

如果需要的话,甚至可以使包装器类作为字典完全发挥作用,尽管这是更多的代码

性能角度来看,这当然不是一个胜利,但是从程序员友好的角度来看,我喜欢它。第二种方法应该稍微快一点,因为它没有在每次删除时测试标志。

其他 2022/1/1 18:44:39 有299人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶