Reverse / invert a dictionary mapping

前端 未结 26 2212
一整个雨季
一整个雨季 2020-11-21 11:47

Given a dictionary like so:

my_map = {\'a\': 1, \'b\': 2}

How can one invert this map to get:

inv_map = {1: \'a\', 2: \'b\'         


        
相关标签:
26条回答
  • 2020-11-21 11:52

    If values aren't unique AND may be a hash (one dimension):

    for k, v in myDict.items():
        if len(v) > 1:
            for item in v:
                invDict[item] = invDict.get(item, [])
                invDict[item].append(k)
        else:
            invDict[v] = invDict.get(v, [])
            invDict[v].append(k)
    

    And with a recursion if you need to dig deeper then just one dimension:

    def digList(lst):
        temp = []
        for item in lst:
            if type(item) is list:
                temp.append(digList(item))
            else:
                temp.append(item)
        return set(temp)
    
    for k, v in myDict.items():
        if type(v) is list:
            items = digList(v)
            for item in items:
                invDict[item] = invDict.get(item, [])
                invDict[item].append(k)
        else:
            invDict[v] = invDict.get(v, [])
            invDict[v].append(k)
    
    0 讨论(0)
  • 2020-11-21 11:54

    Assuming that the values in the dict are unique:

    dict((v, k) for k, v in my_map.iteritems())
    
    0 讨论(0)
  • 2020-11-21 11:54

    Another, more functional, way:

    my_map = { 'a': 1, 'b':2 }
    dict(map(reversed, my_map.items()))
    
    0 讨论(0)
  • 2020-11-21 11:56

    If the values in my_map aren't unique:

    inv_map = {}
    for k, v in my_map.iteritems():
        inv_map[v] = inv_map.get(v, []) + [k]
    
    0 讨论(0)
  • 2020-11-21 11:56

    This expands upon the answer by Robert, applying to when the values in the dict aren't unique.

    class ReversibleDict(dict):
    
        def reversed(self):
            """
            Return a reversed dict, with common values in the original dict
            grouped into a list in the returned dict.
    
            Example:
            >>> d = ReversibleDict({'a': 3, 'c': 2, 'b': 2, 'e': 3, 'd': 1, 'f': 2})
            >>> d.reversed()
            {1: ['d'], 2: ['c', 'b', 'f'], 3: ['a', 'e']}
            """
    
            revdict = {}
            for k, v in self.iteritems():
                revdict.setdefault(v, []).append(k)
            return revdict
    

    The implementation is limited in that you cannot use reversed twice and get the original back. It is not symmetric as such. It is tested with Python 2.6. Here is a use case of how I am using to print the resultant dict.

    If you'd rather use a set than a list, and there could exist unordered applications for which this makes sense, instead of setdefault(v, []).append(k), use setdefault(v, set()).add(k).

    0 讨论(0)
  • 2020-11-21 11:57

    I would do it that way in python 2.

    inv_map = {my_map[x] : x for x in my_map}
    
    0 讨论(0)
提交回复
热议问题