【问题标题】:What's the best way to create exchangeable tuple keys for the same dictionary value?为相同的字典值创建可交换元组键的最佳方法是什么?
【发布时间】:2017-05-06 16:23:42
【问题描述】:
def check():
    dict_choice_a = {(a, b) : value, (b, a) : value}  #(a, b) and (b, a) refer to the same value but repeted
    dict_choice_b = {tuple(sorted((a, b)) : value}  #not repetitive but unreadable
    dict_choice_a[(a, b)] = new_value #need to do twice to change value but more readable than dict_choice_b
    dict_choice_a[(b, a)] = new_value

    #value of both keys are always the same

我想创建一个 dictionary,其中包含引用其值的元组键,该键需要可交换为 (a, b) = (b, a),并且它们仅引用相同的值。

这里的问题是:使 tulpe of keys 的元素可交换但也引用相同值的最佳方法是什么。

此外,字符串也应该在解决方案中起作用。

【问题讨论】:

  • 你可以用set代替tuple
  • @Ni。 frozensetsets 不可散列,因此不能作为键
  • 对,好点。

标签: python sorting dictionary tuples


【解决方案1】:

根据 cmets,您可以将 ab 放入无序的 frozenset

dict_choice = {frozenset((a, b)): value}

如果您需要自动执行此操作,您可以创建自己的MutableMapping

class MyDict(MutableMapping):

    def __init__(self, arg=None):
        self._map = {}
        if arg is not None:
            self.update(arg)

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

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

    def __delitem__(self, key):
        del self._map[frozenset(key)]

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

    def __len__(self):
        return len(self._map)

使用中:

>>> d = MyDict([((1, 2), 'hello'), ((3, 4), 'world')])
>>> d[(2, 1)]
'hello' 

但是请注意,这可能会对其他类型的键产生意外行为:

>>> d['hello'] = 'world'
>>> d['hole']
'world'
>>> d[1] = 2
Traceback (most recent call last):
  File "python", line 1, in <module>
  File "python", line 14, in __setitem__
TypeError: 'int' object is not iterable

【讨论】:

    【解决方案2】:

    使用@jonrsharpe 解决方案,我为其他类型的键的意外行为创建了一个替代方案,考虑到只有元组将以无序的方式使用:

    class MyDict(MutableMapping):
    
        def __init__(self, arg=None):
            self._map = {}
            if arg is not None:
                self.update(arg)
    
        def __getitem__(self, key):
            if isinstance(key, tuple):
                return self._map[frozenset(key)]
            return self._map[key]
    
        def __setitem__(self, key, value):
            if isinstance(key, tuple):
                self._map[frozenset(key)] = value
            else:
                self._map[key] = value
    
        def __delitem__(self, key):
            if isinstance(key, tuple):
                del self._map[frozenset(key)]
            else:
                del self.map[key]
    
        def __iter__(self):
            return iter(self._map)
    
        def __len__(self):
            return len(self._map)
    
        def __str__(self):
            return str(self._map)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 2021-11-26
      • 1970-01-01
      相关资源
      最近更新 更多