Frage

Gegeben sei ein Wörterbuch wie folgt:

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

Wie kann man diese Karte umkehren, um Folgendes zu erhalten:

inv_map = { 1: 'a', 2: 'b' }
War es hilfreich?

Lösung

Für Python 2.7.x

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

Für Python 3 +:

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

Andere Tipps

Unter der Annahme, dass die Werte in der dict sind einzigartig:

dict((v, k) for k, v in my_map.iteritems())

Wenn die Werte in my_map sind nicht eindeutig:

inv_map = {}
for k, v in my_map.iteritems():
    inv_map[v] = inv_map.get(v, [])
    inv_map[v].append(k)

Um dies zu tun, während die Art Ihres Mapping-Erhaltung (unter der Annahme, dass es eine dict oder eine dict Unterklasse ist):

def inverse_mapping(f):
    return f.__class__(map(reversed, f.items()))

Versuchen Sie folgendes:

inv_map = dict(zip(my_map.values(), my_map.keys()))

(Beachten Sie, dass ausdrücklich garantieren, dass .keys() und .values() haben ihre Elemente in der gleichen Reihenfolge, die oben auf der Arbeit den Ansatz erlaubt.)

Alternativ:

inv_map = dict((my_map[k], k) for k in my_map)

oder Python 3.0 der dict Comprehensions mit

inv_map = {my_map[k] : k for k in my_map}

Eine andere, funktional, Art und Weise:

my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))

Dies erweitert die Antwort https://stackoverflow.com/questions/ 483.666 / python-Reverse-invers-a-Kartierungs- / 485368 # 485368 , Anwendung, wenn die Werte in der dict sind nicht eindeutig.

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

Die Umsetzung wird dadurch begrenzt, dass Sie nicht reversed zweimal verwenden können und das Original zurück. Es ist nicht als solche symmetrisch. Es ist mit Python 2.6 getestet. Hier ist ein Anwendungsfall, wie ich das resultierende dict drucken verwende.

Wenn Sie lieber ein set als ein list verwenden würde, und es gibt Anwendungen, bei denen es sinnvoll ist, statt setdefault(v, []).append(k) verwenden setdefault(v, set()).add(k).

Wir können auch ein Wörterbuch mit Nachschlüssel mit defaultdict Reverse:

from collections import Counter, defaultdict

def invert_dict(d):
    d_inv = defaultdict(list)
    for k, v in c.items():
        d_inv[v].append(k)
    return d_inv

text = 'aaa bbb ccc ddd aaa bbb ccc aaa' 
c = Counter(text.split()) # Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ddd': 1})
dict(invert_dict(c)) # {1: ['ddd'], 2: ['bbb', 'ccc'], 3: ['aaa']}  

Siehe hier :

  

Diese Technik ist einfacher und schneller als eine äquivalente Technik dict.setdefault().

Die Kombination von Liste und Wörterbuch Verständnis. Kann Griff Nachschlüssel

{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}

Hinzufügen my 2 cents von pythonic Art und Weise:

inv_map = dict(map(reversed, my_map.items()))

Beispiel:

In [7]: my_map
Out[7]: {1: 'one', 2: 'two', 3: 'three'}

In [8]: inv_map = dict(map(reversed, my_map.items()))

In [9]: inv_map
Out[9]: {'one': 1, 'three': 3, 'two': 2}

Wenn die Werte nicht eindeutig sind, und Sie sind ein wenig hardcore:

inv_map = dict(
    (v, [k for (k, xx) in filter(lambda (key, value): value == v, my_map.items())]) 
    for v in set(my_map.values())
)

Vor allem für eine große dict, beachten Sie, dass diese Lösung weit weniger effizient als die Antwort ist

Zusätzlich zu den anderen Funktionen oben vorgeschlagen, wenn Sie lambda mögen:

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

Oder könnten Sie es auf diese Weise auch tun:

invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )

Ich denke, der beste Weg, dies zu tun ist, um eine Klasse zu definieren. Hier ist eine Implementierung eines „symmetrischen Wörterbuch“:

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

Löschen und Iterationsverfahren sind einfach genug, um zu implementieren, wenn sie benötigt werden.

Diese Implementierung ist viel effizienter als ein ganzes Wörterbuch Umkehren (das ist die beliebteste Lösung auf dieser Seite zu sein scheint). Ganz zu schweigen davon, können Sie Werte aus Ihrem SymDict hinzuzufügen oder zu entfernen, so viel wie Sie wollen, und Ihr Invers Wörterbuch wird immer bleiben gültig -. Das ist nicht wahr, wenn Sie einfach das gesamte Wörterbuch umkehren einmal

Mit zip

inv_map = dict(zip(my_map.values(), my_map.keys()))

Dadurch werden nicht eindeutige Werte verarbeitet und ein Großteil des Aussehens des eindeutigen Falls beibehalten.

inv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}

Für Python 3.x ersetzen Iterwerte mit Werte.Das kann ich mir nicht anrechnen lassen...Es wurde von Icon Jack vorgeschlagen.

Versuchen Sie, diese für Python 2.7 / 3.x

inv_map={};
for i in my_map:
    inv_map[my_map[i]]=i    
print inv_map

Zum Beispiel, Sie haben folgendes Wörterbuch:

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

Und wollen Sie es in einer solchen invertierten Form erhalten:

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

Erste Lösung . Zum Umkehren Schlüsselwert Paare in Ihrem Wörterbuch einen for-Loop-Ansatz verwenden:

# Use this code to invert dictionaries that have non-unique values

inverted_dict = dictio()
for key, value in dict.items():
    inverted_dict.setdefault(value, list()).append(key)

Zweite Lösung . Verwenden Sie ein Wörterbuch Verständnis Ansatz zur Inversion:

# Use this code to invert dictionaries that have unique values

inverted_dict = {value: key for key, value in dict.items()}

dritte Lösung . Verwenden Sie Zurücksetzen der Inversion Ansatz:

# 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]}

Die Funktion ist symmetrisch für Werte vom Typ Liste; Tupel werden in Listen umgewandelt, wenn der Rückwärts dict (Reverse dict (Wörterbuch)) Durchführen

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

Da Worte einen eindeutigen Schlüssel im Wörterbuch im Gegensatz zu Werte erfordern, haben wir die umgekehrten Werte in eine Liste von Art anhänge innerhalb der neuen spezifischen Schlüssel enthalten sein.

def r_maping(dictionary):
    List_z=[]
    Map= {}
    for z, x in dictionary.iteritems(): #iterate through the keys and values
        Map.setdefault(x,List_z).append(z) #Setdefault is the same as dict[key]=default."The method returns the key value available in the dictionary and if given key is not available then it will return provided default value. Afterward, we will append into the default list our new values for the specific key.
    return Map

Ich würde es tun, dass die Art und Weise in Python 2.

inv_map = {my_map[x] : x for x in my_map}
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})

Dies wird als Output: {1: [ 'a', 'd'], 2: [ 'b'], 3: [ 'c']}

  def reverse_dictionary(input_dict):
      out = {}
      for v in input_dict.values():  
          for value in v:
              if value not in out:
                  out[value.lower()] = []

      for i in input_dict:
          for j in out:
              if j in map (lambda x : x.lower(),input_dict[i]):
                  out[j].append(i.lower())
                  out[j].sort()
      return out

Dieser Code tun wie folgt aus:

r = reverse_dictionary({'Accurate': ['exact', 'precise'], 'exact': ['precise'], 'astute': ['Smart', 'clever'], 'smart': ['clever', 'bright', 'talented']})

print(r)

{'precise': ['accurate', 'exact'], 'clever': ['astute', 'smart'], 'talented': ['smart'], 'bright': ['smart'], 'exact': ['accurate'], 'smart': ['astute']}

Fast funktionelle Lösung für nicht-bijektiv Karten (Werte nicht eindeutig):

from itertools import imap, groupby

def fst(s):
    return s[0]

def snd(s):
    return s[1]

def inverseDict(d):
    """
    input d: a -> b
    output : b -> set(a)
    """
    return {
        v : set(imap(fst, kv_iter))
        for (v, kv_iter) in groupby(
            sorted(d.iteritems(),
                   key=snd),
            key=snd
        )
    }

In der Theorie sollte dies schneller sein als auf den Satz hinzugefügt (oder in die Liste angehängt) nacheinander wie in der zwingend notwendig Lösung .

Leider sind die Werte sein sortierbar haben, wird die Sortierung von groupby erforderlich.

Nicht etwas ganz anderes, nur ein bisschen neu geschrieben Rezept aus Kochbuch. Es ist futhermore durch die Beibehaltung setdefault Verfahren optimiert, anstatt jedes Mal durch die Instanz bekommen:

def inverse(mapping):
    '''
    A function to inverse mapping, collecting keys with simillar values
    in list. Careful to retain original type and to be fast.
    >> d = dict(a=1, b=2, c=1, d=3, e=2, f=1, g=5, h=2)
    >> inverse(d)
    {1: ['f', 'c', 'a'], 2: ['h', 'b', 'e'], 3: ['d'], 5: ['g']}
    '''
    res = {}
    setdef = res.setdefault
    for key, value in mapping.items():
        setdef(value, []).append(key)
    return res if mapping.__class__==dict else mapping.__class__(res)

Entwickelt unter CPython 3.x ausgeführt werden, für 2.x ersetzen mapping.items() mit mapping.iteritems()

Auf meinem Rechner läuft etwas schneller, als andere Beispiele hier

Wenn die Werte nicht eindeutig sind und können ein Hash (eine Dimension) sein:

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)

Und mit einer Rekursion, wenn Sie tiefer graben müssen dann nur eine 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)

Inverse Ihr Wörterbuch:

dict_ = {"k0":"v0", "k1":"v1", "k2":"v1"}
inversed_dict_ = {val: key for key, val in dict_.items()}

print(inversed_dict_["v1"])

Ich schrieb dies mit Hilfe des Zyklus ‚für‘ und Methode ‚.get ()‘ und ich änderte den Namen ‚Landkarte‘ des Wörterbuchs zu ‚map1‘, weil ‚Karte‘ ist eine Funktion.

def dict_invert(map1):
    inv_map = {} # new dictionary
    for key in map1.keys():
        inv_map[map1.get(key)] = key
    return inv_map

Für alle Arten von Wörterbuch, ganz gleich, ob sie nicht über eindeutige Werte als Schlüssel zu verwenden, können Sie eine Liste der Schlüssel für jeden Wert erstellen

inv_map = {v: inv_map.get(v, []) + [k] for k,v in my_map.items()}

Dies ist nicht die beste Lösung, aber es funktioniert. Sagen wir mal das Wörterbuch wir umkehren wollen, ist:

Wörterbuch = { 'a': 1, 'b': 2 'c': 3}, dann gilt:

dictionary = {'a': 1, 'b': 2, 'c': 3}
reverse_dictionary = {}
for index, val in enumerate(list(dictionary.values())):
    reverse_dictionary[val] = list(dictionary.keys())[index]

Der Ausgang des reverse_dictionary sollte {1: 'a', 2: 'b', 3: 'c'}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top