【问题标题】:A python class that is a 1-1 mapping of items, inheriting from dict一个python类,是项目的1-1映射,继承自dict
【发布时间】:2018-09-26 15:58:24
【问题描述】:

我从 dict 类继承并尝试对项目进行 1 对 1 映射。

我正在尝试实现给定的 setitem 而不是 key:value key1:key 2, key2:key1 也被添加。 如果其中任何一个键已经存在,则应在添加对之前弹出它们。我该如何实现 setitem

init 应该能够构造一个空映射或来自给定字典的映射

有什么想法吗?谢谢

class Mapping(dict):
    def __init__(self, Map = None):
        if Map = None:
            Map = dict()
        else:
            self.update(Map)

    def __repr__(self):
        return "Mapping({})".format(dict.__repr__self)
    def pop(self):
        return self.pop   #??? How can I pop a key and also pop the key it maps to?
    def __setitem__(self, key1,key2):
        self.__dict__[key1] = key2
        self.__dict__[key2] = key1

【问题讨论】:

  • pop 应该接受一个论点。 dict.pop 以键为参数
  • 你也不想使用dict()作为Map的默认值;使用None,并分配一个新的dict inside __init__ if Map is None.
  • 如果你有 1 映射到 2 和 3 映射到 4,然后你做map[2] = 3,现有的映射会发生什么?他们都被删除了吗?
  • @user2357112 如果密钥 1 或密钥 2 已经存在,那么在添加对之前应该弹出它们是
  • 注意:dict 更新不使用 setitem

标签: python python-3.x class dictionary inheritance


【解决方案1】:

pop 将键作为参数并返回与其关联的值。因此,将您从弹出 key1 中获得的值作为 key2 弹出。

你可以self.__dict__.pop(self.__dict__.pop(key))

【讨论】:

  • @TwistedSim 如果 key == value 为什么这不起作用?
  • 因为你会弹出两次钥匙
  • 其实你可能需要'key is item' 需要测试!
【解决方案2】:

你可以尝试做这样的事情:

from collections.abc import MutableMapping

# We need to implement those method: __getitem__, __setitem__, __delitem__, __iter__, __len__

class TwoWayDict(MutableMapping):

    __slots__ = '__dict__'

    def __init__(self, *args, **kwargs):
        self.__dict__.update(*args, **kwargs)
    def __getitem__(self, key):
        return self.__dict__[key]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
        self.__dict__[value] = key
    def __delitem__(self, key):
        self.__dict__.__delitem__(self[self[key]])            
        self.__dict__.__delitem__(self[key])  # this do not work if key == value
    def __iter__(self):
        return iter(self.__dict__)
    def __len__(self):
        return len(self.__dict__)
    def get(self, key, default=None):
        return self[key] if key in self else default
    def __str__(self):
        return str(self.__dict__)

测试:

a = TwoWayDict()
a['key1'] = 'key2'
print(a)
print(a['key1'])
print(a['key2'])
print(len(a))
for key, val in a.items():
    print(key, val)

结果:

{'key1': 'key2', 'key2': 'key1'}
key2
key1
2
key1 key2
key2 key1

请注意,长度和迭代可能不明确。如果您不想显示重复键,则需要在 dict 项中找到键并返回相应的键。对于流行音乐,您可以使用 SW Williams 提出的解决方案。

编辑:如果你真的需要从 dict 继承(可能是一个赋值......)不要忘记实现更新,因为它会绕过 __setitem__ 并进入 dict。此外,如果您有一个 1 对 1 的键映射,您需要在 __del____pop__ 函数中处理这个问题。

【讨论】:

  • 谢谢,但我真的在尝试使用字典而不是映射来实现 setitem
  • 我必须说,你只是实现了__setitem__,除了你之外的大部分行为都行不通。在上面的答案中查看我的编辑。
猜你喜欢
  • 1970-01-01
  • 2014-09-24
  • 2012-03-20
  • 2015-07-01
  • 1970-01-01
  • 2010-10-26
  • 2015-10-09
  • 2015-05-23
  • 1970-01-01
相关资源
最近更新 更多