Подтвердить что ты не робот

Python: лучший способ обмена ключами со значениями в словаре?

Я получаю словарь в качестве входных данных и хотел бы вернуть словарь, чьими ключами будут входные значения и значение которых будет соответствовать соответствующим клавишам ввода. Значения уникальны.

Например, скажем, что мой вход:

a = dict()
a['one']=1
a['two']=2

Я хотел бы, чтобы мой вывод был:

{1: 'one', 2: 'two'}

Чтобы уточнить, я хотел бы, чтобы мой результат был эквивалентным следующему:

res = dict()
res[1] = 'one'
res[2] = 'two'

Какой-нибудь опрятный питонский способ достичь этого?

Спасибо

4b9b3361

Ответ 1

Python 2:

res = dict((v,k) for k,v in a.iteritems())

Python 3 (спасибо @erik):

res = dict((v,k) for k,v in a.items())

Ответ 2

new_dict = dict (zip(my_dict.values(),my_dict.keys()))

Ответ 3

Из Python 2.7, включая 3.0+, есть, возможно, более короткая, более читаемая версия:

>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}

Ответ 4

In [1]: my_dict = {'x':1, 'y':2, 'z':3}

In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}

Ответ 5

Вы можете использовать словесное понимание:

res = {v: k for k, v in a.iteritems()}

Отредактировано: для Python 3 используйте a.items() вместо a.iteritems(). Обсуждение различий между ними можно найти в итериментах Python для SO.

Ответ 6

Вы можете попробовать:

d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
  {'two': 2, 'one': 1}

Помните, что вы не можете "перевернуть" словарь, если

  • Более одного ключа имеют одинаковое значение. Например {'one':1,'two':1}. Новый словарь может содержать только один элемент с ключом 1.
  • Одно или несколько значений не сбрасываются. Например {'one':[1]}. [1] является допустимым значением, но не действительным ключом.

См. этот поток в списке рассылки python для обсуждения темы.

Ответ 7

new_dict = dict( (my_dict[k], k) for k in my_dict)

или даже лучше, но работает только в Python 3:

new_dict = { my_dict[k]: k for k in my_dict}

Ответ 8

res = dict(zip(a.values(), a.keys()))

Ответ 9

Еще один способ расширить ответ на Илья Прокин - фактически использовать функцию reversed.

dict(map(reversed, my_dict.items()))

В сущности, ваш словарь итерируется через (используя .items()), где каждый элемент является парой ключ/значение, и эти элементы обмениваются с помощью функции reversed. Когда это передается конструктору dict, он превращает их в пары значений/ключей, которые вы хотите.

Ответ 10

Текущий ведущий ответ предполагает, что значения уникальны, что не всегда так. Что делать, если значения не уникальны? Вы потеряете информацию! Например:

d = {'a':3, 'b': 2, 'c': 2} 
{v:k for k,v in d.iteritems()} 

возвращает {2: 'b', 3: 'a'}.

Информация о 'c' была полностью проигнорирована. В идеале это должно было быть чем-то вроде {2: ['b','c'], 3: ['a']}. Это то, что делает нижняя реализация.

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.iteritems():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

Ответ 11

Рекомендация для улучшения ответа Хавьера:

dict(zip(d.values(),d))

Вместо d.keys() вы можете написать только d, потому что если вы перейдете через словарь с итератором, он вернет ключи соответствующего словаря.

Ex. для этого поведения:

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'

Ответ 12

dict(map(lambda x: x[::-1], YourDict.items()))

.items() возвращает список кортежей (key, value). map() проходит через элементы списка и применяет lambda x:[::-1] к каждому его элементу (кортежу), чтобы отменить его, поэтому каждый кортеж становится (value, key) в новом списке, выведенном из карты. Наконец, dict() делает dict из нового списка.

Ответ 13

Может быть легко сделано с пониманием словаря:

{d[i]:i for i in d}

Ответ 14

Использование loop: -

newdict = {} #Will contain reversed key:value pairs.

for key, value in zip(my_dict.keys(), my_dict.values()):
    # Operations on key/value can also be performed.
    newdict[value] = key

Ответ 15

Если вы используете Python3, он немного отличается:

res = dict((v,k) for k,v in a.items())

Ответ 16

Добавление решения на месте:

>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
...     d[d.pop(k)] = k
... 
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}

В Python3 очень важно использовать list(d.keys()), потому что dict.keys возвращает вид ключей. Если вы используете Python2, d.keys() достаточно.

Ответ 17

res = dict(zip(a.values(), a.keys()))