web-dev-qa-db-ja.com

Python:辞書の値とキーを交換する最良の方法は?

辞書を入力として受け取り、キーが入力の値になり、値が対応する入力キーになる辞書を返したいと思います。値は一意です。

たとえば、私の入力は次のとおりです。

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

出力を次のようにします。

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

明確にするために、私の結果が次と同等になるようにしたいと思います。

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

これを達成するためのPythonのきちんとした方法はありますか?

ありがとう

80
Roee Adler

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())
130
liori
new_dict = dict (Zip(my_dict.values(),my_dict.keys()))
52
Javier

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'}
44
SilentGhost
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'}
30
sunqiang

dict内包表記 を使用できます:

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

編集:Python 3の場合、a.items()の代わりにa.iteritems()を使用してください。それらの違いについての議論は Pythonのiteritems SO.

27
Akavall

あなたが試すことができます:

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

次の場合は辞書を「逆」にできないことに注意してください

  1. 複数のキーが同じ値を共有します。例えば ​​{'one':1,'two':1}。新しい辞書には、キー1
  2. 1つ以上の値がハッシュ不能です。例えば ​​{'one':[1]}[1]は有効な値ですが、有効なキーではありません。

このテーマに関する議論については、pythonメーリングリストの this thread を参照してください。

18
Alasdair
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}
14
balpha

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

13
pkit

Ilya Prokin の応答を拡張する別の方法は、実際にreversed関数を使用することです。

_dict(map(reversed, my_dict.items()))
_

本質的に、辞書は(.items()を使用して)反復処理され、各項目はキー/値のペアであり、それらの項目はreversed関数と交換されます。これがdictコンストラクタに渡されると、値/キーのペアに変換されます。

10
Sunny Patel

現在の主な回答では、値が一意であると想定していますが、常にそうであるとは限りません。値が一意でない場合はどうなりますか?情報が失われます!例えば:

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
10

ハビエルの答えの改善のための提案:

_dict(Zip(d.values(),d))
_

d.keys()の代わりにdだけを書くことができます。なぜなら、イテレータで辞書を調べると、関連する辞書のキーが返されるからです。

例この動作の場合:

_d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'
_
6
shadow2097
_dict(map(lambda x: x[::-1], YourDict.items()))
_

.items()は_(key, value)_のタプルのリストを返します。 map()はリストの要素を通過し、それぞれの要素(タプル)に_lambda x:[::-1]_を適用して逆にします。そのため、各タプルはマップから吐き出された新しいリストで_(value, key)_になります。最後に、dict()は新しいリストから辞書を作成します。

2
Ilya Prokin

辞書の理解で簡単にできます:

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

インプレースソリューションの追加:

_>>> 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()で十分です。

1
timgeb

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
1
Devesh Saini

Python3を使用している場合、少し異なります。

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