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

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

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

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

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

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

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

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

Любой аккуратный Pythonian способ достичь этого?

Спасибо

 o0'.20 окт. 2011 г., 14:55
Python не является Perl, Python не является Ruby. Читаемость имеет значение. Разреженный лучше, чем плотный. Учитывая это, все методы этих ответов просто плохи & # x2122 ;; тот, о котором идет речь, - лучший путь.
 Roee Adler25 сент. 2009 г., 07:36
@ Стефан: см. Второй ответ с наибольшим количеством голосов, он такой же, как принятый в вопросе, с которым вы связаны. Толпа предпочла другой ответ, хотя ...
 Stephen Edmonds24 сент. 2009 г., 14:48
Увидетьstackoverflow.com/questions/1087694/… на идентичный вопрос, на который есть хороший ответ, если вы используете Python 3
 Cory05 апр. 2014 г., 00:44
возможный дубликатPython reverse / inverse a mapping

Ответы на вопрос(16)

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

new_dict = { my_dict[k]: k for k in my_dict}
 11 нояб. 2013 г., 11:53
На самом деле Dict Понимания (PEP 274) работать с Python 2.7 также.

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

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

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

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

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

Помните, что вы не можете «повернуть вспять»; словарь, если

More than one key shares the same value. For example {'one':1,'two':1}. The new dictionary can only have one item with key 1. One or more of the values is unhashable. For example {'one':[1]}. [1] is a valid value but not a valid key.

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

 Roee Adler23 июн. 2009 г., 13:05
+1 я добавил примечание о уникальности значений, спасибо
 06 апр. 2011 г., 20:45
Также +1 за примечание о том, что значения в оригинальном dict уникальны; в противном случае вы будете перезаписаны на "перевернутый"; dict ... и это (я только что нашел это за мою цену) может вызвать хитрые ошибки в вашем коде!
 Roee Adler23 июн. 2009 г., 13:04
Лиори уже предоставил это решение, но спасибо

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

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
 03 мар. 2019 г., 20:00
это должен быть правильный ответ, так как он охватывает более общий случай

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

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

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

Предложение по улучшению ответа Хавьера:

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

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

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

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

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
Решение Вопроса

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())
 04 авг. 2017 г., 00:44
Что если значения не являются уникальными? Тогда ключи должны быть списком ... например: d = {'a': 3, 'b': 2, 'c': 2} {v: k для k, v в d.iteritems ( )} {2: 'b', 3: 'a'} должно быть {2: ['' b ',' c '], 3:' a '}
 29 нояб. 2018 г., 18:37
код python2 работает ... но понимание списка отсутствует[ а также], для понимания списка не требуется[ а также]?
 10 сент. 2015 г., 21:49
Хотя это кажется правильным, полезно добавить объяснение того, как это работает, а не просто код.
 24 апр. 2016 г., 00:37
Для Python3 это было быres = {v:k for k,v in a.items()}.
 04 авг. 2017 г., 11:17
@HananShteingart: заявленные в вопросе значения являются уникальными. Пожалуйста, создайте отдельный пост с вопросом для вашего случая (и, желательно, разместите ссылку здесь для других людей).

>>> 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 возвращаетview из ключей. Если вы используете Python2,d.keys() достаточно.

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'}
 06 июл. 2009 г., 17:51
@Andre Miller: требуется последнее вхождение определенного ключа: dict (((1,3), (1,2))) == {1: 2}
 06 июл. 2009 г., 17:49
Не в первоначальном вопросе, мне просто любопытно, что произойдет, если у вас будут повторяющиеся значения в исходном словаре, а затем поменяйте местами ключ / значения этим методом?
 06 июл. 2009 г., 17:52
дубликаты будут перезаписаны последним обнаруженным дублированием.
 06 июл. 2009 г., 17:53
Я думаю, что это займет последнюю пару ключ, значение, которое он нашел. Это похоже на ['x'] = 3. Затем вы устанавливаете ['x'] = 4.
 06 июл. 2009 г., 17:53
@Andre Miller: А поскольку d.items () возвращает элементы в произвольном порядке, вы получаете произвольный ключ для повторяющихся значений.
dict(map(lambda x: x[::-1], YourDict.items()))

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

 08 авг. 2015 г., 00:25
Можете ли вы объяснить, как это работает?
 10 сент. 2015 г., 21:27
.items () возвращает список кортежей (ключ, значение). map () просматривает элементы списка и применяетlambda x:[::-1] каждому его элементу (кортежу), чтобы обратить его, так что каждый кортеж становится (значение, ключ) в новом списке, выделенном из карты. Наконец, dict () делает диктат из нового списка.

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

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

включая 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'}

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

 23 июн. 2009 г., 13:05
Вы правы. Ваш ответ более эффективен.
 23 июн. 2009 г., 13:32
nosklo, что если другой поток изменяет словарь?
 23 июн. 2009 г., 13:16
Хорошо, тогда я ошибаюсь ... Я не проверял онлайн-документы. Спасибо, что указали на это.
 23 июн. 2009 г., 13:01
dict не гарантирует, что его values () и keys () будут возвращать элементы в том же порядке. Кроме того, keys (), values () и zip () возвращают список, где итератора будет достаточно.
 23 июн. 2009 г., 13:12
@liori: Ты не прав. dict гарантирует, что его values () и keys () будут в одном и том же порядке, если вы, конечно, не изменяете dict между вызовами values () и keys (). Документация гласит, что здесь: (прочитайте раздел «Примечание»:docs.python.org/library/stdtypes.html#dict.items) & quot; Если items (), keys (), values (), iteritems (), iterkeys () и itervalues () вызываются без промежуточных модификаций словаря, списки будут напрямую соответствовать. & quot;
new_dict = dict (zip(my_dict.values(),my_dict.keys()))
 06 июл. 2009 г., 18:37
См. Примечание к заказу наdocs.python.org/library/stdtypes.html#dict.items
 06 июл. 2009 г., 18:28
Действительно ли values () и keys () имеют одинаковый порядок?
 06 июл. 2009 г., 18:39
да, изpython.org/dev/peps/pep-3106 Спецификация подразумевает, что порядок, в котором элементы возвращаются с помощью .keys (), .values () и .items (), одинаков (так же, как это было в Python 2.x), потому что порядок является производным от dict итератор (который, по-видимому, произвольный, но устойчивый до тех пор, пока диктовка не модифицирована). но этот ответ должен вызвать my_dict дважды (один для значений, один для ключей). может быть, это не идеально.
 07 июл. 2009 г., 19:59
Да, этот ответ повторяет диктовку дважды. Ответ Sunqiang предпочтителен для большого словаря, поскольку он требует только одну итерацию.
 07 июл. 2009 г., 21:26
@Carl Meyer: согласен, он также использует itertools, которые намного лучше подходят для больших наборов данных. хотя мне интересно, если последний вызов dict () также потоковый, или он сначала собирает весь список пар

Ваш ответ на вопрос