Reverse / invert a dictionary mapping

前端 未结 26 2215
一整个雨季
一整个雨季 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 12:09

    Function is symmetric for values of type list; Tuples are coverted to lists when performing reverse_dict(reverse_dict(dictionary))

    def reverse_dict(dictionary):
        reverse_dict = {}
        for key, value in dictionary.iteritems():
            if not isinstance(value, (list, tuple)):
                value = [value]
            for val in value:
                reverse_dict[val] = reverse_dict.get(val, [])
                reverse_dict[val].append(key)
        for key, value in reverse_dict.iteritems():
            if len(value) == 1:
                reverse_dict[key] = value[0]
        return reverse_dict
    
    0 讨论(0)
  • 2020-11-21 12:12

    Python 3+:

    inv_map = {v: k for k, v in my_map.items()}
    

    Python 2:

    inv_map = {v: k for k, v in my_map.iteritems()}
    
    0 讨论(0)
  • 2020-11-21 12:12

    For instance, you have the following dictionary:

    dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', 'd': 'water'}
    

    And you wanna get it in such an inverted form:

    inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}
    

    First Solution. For inverting key-value pairs in your dictionary use a for-loop approach:

    # Use this code to invert dictionaries that have non-unique values
    
    inverted_dict = dict()
    for key, value in dict.items():
        inverted_dict.setdefault(value, list()).append(key)
    

    Second Solution. Use a dictionary comprehension approach for inversion:

    # Use this code to invert dictionaries that have unique values
    
    inverted_dict = {value: key for key, value in dict.items()}
    

    Third Solution. Use reverting the inversion approach (relies on second solution):

    # Use this code to invert dictionaries that have lists of values
    
    dict = {value: key for key in inverted_dict for value in my_map[key]}
    
    0 讨论(0)
  • 2020-11-21 12:12
    def invertDictionary(d):
        myDict = {}
      for i in d:
         value = d.get(i)
         myDict.setdefault(value,[]).append(i)   
     return myDict
     print invertDictionary({'a':1, 'b':2, 'c':3 , 'd' : 1})
    

    This will provide output as : {1: ['a', 'd'], 2: ['b'], 3: ['c']}

    0 讨论(0)
  • 2020-11-21 12:15

    In addition to the other functions suggested above, if you like lambdas:

    invert = lambda mydict: {v:k for k, v in mydict.items()}
    

    Or, you could do it this way too:

    invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
    
    0 讨论(0)
  • 2020-11-21 12:15

    I think the best way to do this is to define a class. Here is an implementation of a "symmetric dictionary":

    class SymDict:
        def __init__(self):
            self.aToB = {}
            self.bToA = {}
    
        def assocAB(self, a, b):
            # Stores and returns a tuple (a,b) of overwritten bindings
            currB = None
            if a in self.aToB: currB = self.bToA[a]
            currA = None
            if b in self.bToA: currA = self.aToB[b]
    
            self.aToB[a] = b
            self.bToA[b] = a
            return (currA, currB)
    
        def lookupA(self, a):
            if a in self.aToB:
                return self.aToB[a]
            return None
    
        def lookupB(self, b):
            if b in self.bToA:
                return self.bToA[b]
            return None
    

    Deletion and iteration methods are easy enough to implement if they're needed.

    This implementation is way more efficient than inverting an entire dictionary (which seems to be the most popular solution on this page). Not to mention, you can add or remove values from your SymDict as much as you want, and your inverse-dictionary will always stay valid -- this isn't true if you simply reverse the entire dictionary once.

    0 讨论(0)
提交回复
热议问题