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

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

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

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

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

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

Ответы [ 31 ]

0 голосов
/ 09 января 2016

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

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
0 голосов
/ 08 ноября 2018

Согласно моему комментарию к вопросу. Я думаю, что самый простой и один вкладыш, который работает как для Python2, так и для Python 3, будет

dict(zip(inv_map.values(), inv_map.keys()))
0 голосов
/ 09 июня 2018

Это не лучшее решение, но оно работает. Скажем, словарь, который мы хотим изменить, это:

dictionary = {'a': 1, 'b': 2, 'c': 3}, затем:

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

Выходные данные reverse_dictionary должны быть {1: 'a', 2: 'b', 3: 'c'}

0 голосов
/ 08 июня 2018

Обратный ваш словарь:

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

print(inversed_dict_["v1"])
0 голосов
/ 01 ноября 2010

Для всех типов словарей, независимо от того, имеют ли они уникальные значения для использования в качестве ключей, вы можете создать список ключей для каждого значения

inv_map = {v: inv_map.get(v, []) + [k] for k,v in my_map.items()}
0 голосов
/ 07 марта 2014

Быстрое функциональное решение для небиективных карт (значения не уникальны):

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

Теоретически это должно быть быстрее, чем добавление к набору (или добавление в список) по одному, как в императивном решении .

К сожалению, значения должны быть сортируемыми, сортировка требуется по группам.

0 голосов
/ 10 января 2017

Если значения не являются уникальными И может быть хешем (одно измерение):

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)

И с рекурсией, если вам нужно копать глубже, чем одно измерение:

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 голосов
/ 24 сентября 2014

Функция симметрична для значений списка типов; Кортежи включаются в списки при выполнении reverse_dict (reverse_dict (словарь))

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 голосов
/ 05 августа 2016

Я написал это с помощью цикла «for» и метода «.get ()» и изменил название «map» в словаре на «map1», потому что «map» - это функция.

def dict_invert(map1):
    inv_map = {} # new dictionary
    for key in map1.keys():
        inv_map[map1.get(key)] = key
    return inv_map
0 голосов
/ 02 августа 2016

Не совсем другое, просто немного переписанный рецепт из Кулинарной книги. Более того, он оптимизирован путем сохранения метода setdefault вместо того, чтобы каждый раз проходить его через экземпляр:

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)

Предназначен для работы под CPython 3.x, для 2.x заменить mapping.items() на mapping.iteritems()

На моей машине работает немного быстрее, чем другие примеры здесь

...