869

次のような辞書があるとします。

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

このマップを反転して取得するにはどうすればよいですか。

inv_map = {1: 'a', 2: 'b'}
4

32 に答える 32

1254

Python 3+:

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

パイソン 2:

inv_map = {v: k for k, v in my_map.iteritems()}
于 2009-01-27T15:24:56.603 に答える
191

dict の値が一意であると仮定します。

パイソン 3:

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

パイソン 2:

dict((v, k) for k, v in my_map.iteritems())
于 2009-01-27T14:50:22.757 に答える
173

の値my_mapが一意でない場合:

Python 3:

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

Python 2:

inv_map = {}
for k, v in my_map.iteritems():
    inv_map[v] = inv_map.get(v, []) + [k]
于 2009-01-27T21:33:26.483 に答える
51

dictマッピングのタイプを保持しながらこれを行うには (それがまたはdictサブクラスであると仮定します):

def inverse_mapping(f):
    return f.__class__(map(reversed, f.items()))
于 2009-11-05T10:41:30.830 に答える
43

これを試して:

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

(ディクショナリ ビューに関する Python ドキュメントでは、要素が同じ順序であることが明示的に保証されていること.keys()に注意してください.values()。これにより、上記のアプローチが機能します。)

または:

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

またはpython 3.0のdict内包表記を使用する

inv_map = {my_map[k] : k for k in my_map}
于 2009-01-27T14:49:46.300 に答える
15

これはRobert による回答を拡張し、dict の値が一意でない場合に適用されます。

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

reversed実装は、2 回使用して元に戻すことができないという点で制限されています。それ自体は対称ではありません。Python 2.6 でテストされています。結果の辞書を印刷するために私が使用している方法の使用例を次に示します。

setaよりも aを使用したい場合でlist、これが理にかなっている順序付けられていないアプリケーションが存在する可能性がある場合は、 の代わりにsetdefault(v, []).append(k)を使用しますsetdefault(v, set()).add(k)

于 2012-10-24T20:40:19.283 に答える
7

リスト内包表記と辞書内包表記の組み合わせ。重複キーを処理できます

{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}
于 2018-04-19T03:24:11.217 に答える
4

多くの回答がありますが、一意でない値を持つ辞書について話している場合に備えて、きれいなものは見つかりませんでした。

解決策は次のとおりです。

from collections import defaultdict

inv_map = defaultdict(list) 
for k, v in my_map.items(): 
    inv_map[v].append(k)

例:

初期辞書の場合my_map = {'c': 1, 'd': 5, 'a': 5, 'b': 10}

次に、上記のコードを実行すると、次のようになります。

{5: ['a', 'd'], 1: ['c'], 10: ['b']}
于 2021-03-01T13:15:35.393 に答える
2

これを行う最善の方法は、クラスを定義することだと思います。「対称辞書」の実装は次のとおりです。

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

削除および反復メソッドは、必要に応じて簡単に実装できます。

この実装は、辞書全体を反転するよりもはるかに効率的です (これは、このページで最も一般的なソリューションのようです)。言うまでもなく、SymDict の値を好きなだけ追加または削除でき、逆辞書は常に有効なままです。これは、辞書全体を一度逆にするだけでは当てはまりません。

于 2014-09-28T06:50:44.103 に答える
1

上で提案した他の関数に加えて、ラムダが好きなら:

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

または、次の方法でも実行できます。

invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
于 2013-04-09T19:20:58.913 に答える
1

値が一意ではなく、少し筋金入りの場合:

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())
)

特に大きな dict の場合、このソリューションは、複数回ループするため、Python の逆/反転マッピングよりもはるかに効率が悪いことに注意してください。items()

于 2010-04-17T20:14:06.983 に答える
0

非全単射マップ (値が一意ではない) の高速関数ソリューション:

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
        )
    }

理論的には、これは命令型ソリューションのように 1 つずつセットに追加 (またはリストに追加) するよりも高速です。

残念ながら、値はソート可能でなければなりません。ソートは groupby で必要です。

于 2014-03-06T20:50:11.423 に答える
0

ディクショナリは、値とは異なり、ディクショナリ内に 1 つの一意のキーを必要とするため、逆の値を並べ替えのリストに追加して、新しい特定のキーに含める必要があります。

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
于 2016-01-09T01:26:12.090 に答える
0

これをpython 2.7/3.xで試してください

inv_map={};
for i in my_map:
    inv_map[my_map[i]]=i    
print inv_map
于 2014-07-25T09:31:58.790 に答える
0

関数はリスト型の値に対して対称的です。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
于 2014-09-24T12:23:00.220 に答える
-1

私はpython 2でそのようにします。

inv_map = {my_map[x] : x for x in my_map}
于 2017-04-26T14:28:34.130 に答える
-2

値が一意ではなく、かつハッシュ (1 次元) の可能性がある場合:

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)

さらに深く掘り下げる必要がある場合は、再帰を使用して、1 つのディメンションのみを使用します。

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)
于 2017-01-10T10:37:35.730 に答える
-2

サイクル「for」とメソッド「.get()」を使ってこれを書き、「map」は関数であるため、辞書の名前「map」を「map1」に変更しました。

def dict_invert(map1):
    inv_map = {} # new dictionary
    for key in map1.keys():
        inv_map[map1.get(key)] = key
    return inv_map
于 2016-08-05T19:47:24.360 に答える