Python обратный / инвертировать отображение - PullRequest
539 голосов
/ 27 января 2009

Приведенный словарь выглядит так:

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

Как можно инвертировать эту карту, чтобы получить:

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

ПРИМЕЧАНИЕ РЕДАКТОРА: map изменено на my_map, чтобы избежать конфликтов со встроенной функцией map. Некоторые комментарии могут быть затронуты ниже.

Ответы [ 31 ]

754 голосов
/ 27 января 2009

Для Python 2.7.x

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

Для Python 3 +:

inv_map = {v: k for k, v in my_map.items()}
165 голосов
/ 27 января 2009

Предполагая, что значения в dict являются уникальными:

dict((v, k) for k, v in my_map.iteritems())
114 голосов
/ 28 января 2009

Если значения в my_map не являются уникальными:

inv_map = {}
for k, v in my_map.iteritems():
    inv_map[v] = inv_map.get(v, [])
    inv_map[v].append(k)
40 голосов
/ 05 ноября 2009
def inverse_mapping(f):
    return f.__class__(map(reversed, f.items()))
31 голосов
/ 27 января 2009

Попробуйте это:

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

inv_map = {my_map[k] : k for k in my_map}
18 голосов
/ 26 февраля 2014

Другой, более функциональный способ:

my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))
7 голосов
/ 25 октября 2012

Это расширяется после ответа Python перевернуть / инвертировать отображение , применяя, когда значения в 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 дважды и получить оригинал обратно. Это не симметрично как таковое. Протестировано с Python 2.6. Здесь - это пример использования того, как я использую для печати результирующий дикт.

Если вы предпочитаете использовать set, а не list, и существуют приложения, для которых это имеет смысл, вместо setdefault(v, []).append(k), используйте setdefault(v, set()).add(k).

7 голосов
/ 19 апреля 2018

Сочетание списка и словаря. Может обрабатывать дубликаты ключей

{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}
5 голосов
/ 27 декабря 2016

Мы также можем перевернуть словарь с дубликатами ключей, используя defaultdict:

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

См. здесь :

Этот метод проще и быстрее, чем эквивалентный метод, использующий dict.setdefault().

5 голосов
/ 03 апреля 2017

Добавление моих 2 центов питонического пути:

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

Пример:

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