Python:用字典中的值交换键的最佳方式?

时间:2021-07-19 00:23:19

I receive a dictionary as input, and would like to to return a dictionary whose keys will be the input's values and whose value will be the corresponding input keys. Values are unique.

我收到一个字典作为输入,我想返回一个字典,它的键将是输入的值,其值将是相应的输入键。值是唯一的。

For example, say my input is:

例如,假设我的输入是:

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

I would like my output to be:

我希望我的输出是:

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

To clarify I would like my result to be the equivalent of the following:

为了澄清这一点,我希望我的结果相当于以下内容:

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

Any neat Pythonian way to achieve this?

有什么简单的勾股定理吗?

Thanks

谢谢

15 个解决方案

#1


87  

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

#2


49  

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

#3


40  

From Python 2.7 on, including 3.0+, there's an arguably shorter, more readable version:

从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


31  

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


24  

You can make use of dict comprehensions:

你可以使用字典的理解:

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

Edited: For Python 3, use a.items() instead of a.iteritems(). Discussions about the differences between them can be found in iteritems in Python on SO.

编辑:对于python3,使用a.items()而不是a.iteritems()。关于它们之间的差异的讨论可以在SO中的iteritems中找到。

#6


18  

You could try:

你可以试试:

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

Beware that you cannot 'reverse' a dictionary if

要注意,如果你想要“反转”字典的话,你是不能的

  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.
  2. 不止一个键具有相同的值。例如{ ' 1 ':1,“两个”:1 }。新字典只有一个条目的键是1。
  3. One or more of the values is unhashable. For example {'one':[1]}. [1] is a valid value but not a valid key.
  4. 其中一个或多个值是不可清洗的。例如{ ' 1 ':[1]}。[1]是一个有效的值,但不是一个有效的键。

See this thread on the python mailing list for a discussion on the subject.

有关这个主题的讨论,请参阅python邮件列表中的这个线程。

#7


14  

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

or even better, but only works in Python 3:

或者更好,但只适用于Python 3:

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

#8


11  

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

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

#9


5  

Another way to expand on Ilya Prokin's response is to actually use the reversed function.

扩展Ilya Prokin响应的另一种方法是使用反转函数。

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

In essence, your dictionary is iterated through (using .items()) where each item is a key/value pair, and those items are swapped with the reversed function. When this is passed to the dict constructor, it turns them into value/key pairs which is what you want.

实质上,您的字典是遍历(使用.items())的,其中每个项都是键/值对,这些项与反向函数交换。当这被传递给dict构造函数时,它将它们转换为值/密匙对,这是您想要的。

#10


5  

The current leading answer assumes values are unique which is not always the case. What if values are not unique? You will loose information! For example:

当前的主导答案假设值是唯一的,但并非总是如此。如果值不是唯一的呢?您将松散的信息!例如:

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

returns {2: 'b', 3: 'a'}.

返回{2:'b', 3: '}。

The information about 'c' was completely ignored. Ideally it should had be something like {2: ['b','c'], 3: ['a']}. This is what the bottom implementation does.

关于“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


4  

Suggestion for an improvement for Javier answer :

关于改善哈维尔回答的建议:

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

Instead of d.keys() you can write just d, because if you go through dictionary with an iterator, it will return the keys of the relevant dictionary.

您可以只编写d而不是d键(),因为如果您使用迭代器遍历字典,它将返回相关字典的键。

Ex. for this behavior :

对于这种行为:

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

#12


2  

If you're using Python3, it's slightly different:

如果你用的是Python3,它有点不同:

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

#13


1  

Using 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

#14


1  

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

.items() returns a list of tuples of (key, value). map() goes through elements of the list and applies lambda x:[::-1] to each its element (tuple) to reverse it, so each tuple becomes (value, key) in the new list spitted out of map. Finally, dict() makes a dict from the new list.

.items()返回一个元组列表(键值)。map()遍历列表中的元素,并将lambda x:[::-1]应用到每个元素(元组)以反转它,因此每个元组在从map中分离出来的新列表中成为(value, key)。最后,dict()从新的列表中发出命令。

#15


1  

Adding an in-place solution:

添加一个就地解决方案:

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

In Python3, it is critical that you use list(d.keys()) because dict.keys returns a view of the keys. If you are using Python2, d.keys() is enough.

在Python3中,使用list(.keys())是非常重要的,因为dict.keys返回键的视图。如果使用Python2, d.keys()就足够了。

#1


87  

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

#2


49  

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

#3


40  

From Python 2.7 on, including 3.0+, there's an arguably shorter, more readable version:

从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


31  

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


24  

You can make use of dict comprehensions:

你可以使用字典的理解:

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

Edited: For Python 3, use a.items() instead of a.iteritems(). Discussions about the differences between them can be found in iteritems in Python on SO.

编辑:对于python3,使用a.items()而不是a.iteritems()。关于它们之间的差异的讨论可以在SO中的iteritems中找到。

#6


18  

You could try:

你可以试试:

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

Beware that you cannot 'reverse' a dictionary if

要注意,如果你想要“反转”字典的话,你是不能的

  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.
  2. 不止一个键具有相同的值。例如{ ' 1 ':1,“两个”:1 }。新字典只有一个条目的键是1。
  3. One or more of the values is unhashable. For example {'one':[1]}. [1] is a valid value but not a valid key.
  4. 其中一个或多个值是不可清洗的。例如{ ' 1 ':[1]}。[1]是一个有效的值,但不是一个有效的键。

See this thread on the python mailing list for a discussion on the subject.

有关这个主题的讨论,请参阅python邮件列表中的这个线程。

#7


14  

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

or even better, but only works in Python 3:

或者更好,但只适用于Python 3:

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

#8


11  

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

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

#9


5  

Another way to expand on Ilya Prokin's response is to actually use the reversed function.

扩展Ilya Prokin响应的另一种方法是使用反转函数。

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

In essence, your dictionary is iterated through (using .items()) where each item is a key/value pair, and those items are swapped with the reversed function. When this is passed to the dict constructor, it turns them into value/key pairs which is what you want.

实质上,您的字典是遍历(使用.items())的,其中每个项都是键/值对,这些项与反向函数交换。当这被传递给dict构造函数时,它将它们转换为值/密匙对,这是您想要的。

#10


5  

The current leading answer assumes values are unique which is not always the case. What if values are not unique? You will loose information! For example:

当前的主导答案假设值是唯一的,但并非总是如此。如果值不是唯一的呢?您将松散的信息!例如:

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

returns {2: 'b', 3: 'a'}.

返回{2:'b', 3: '}。

The information about 'c' was completely ignored. Ideally it should had be something like {2: ['b','c'], 3: ['a']}. This is what the bottom implementation does.

关于“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


4  

Suggestion for an improvement for Javier answer :

关于改善哈维尔回答的建议:

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

Instead of d.keys() you can write just d, because if you go through dictionary with an iterator, it will return the keys of the relevant dictionary.

您可以只编写d而不是d键(),因为如果您使用迭代器遍历字典,它将返回相关字典的键。

Ex. for this behavior :

对于这种行为:

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

#12


2  

If you're using Python3, it's slightly different:

如果你用的是Python3,它有点不同:

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

#13


1  

Using 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

#14


1  

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

.items() returns a list of tuples of (key, value). map() goes through elements of the list and applies lambda x:[::-1] to each its element (tuple) to reverse it, so each tuple becomes (value, key) in the new list spitted out of map. Finally, dict() makes a dict from the new list.

.items()返回一个元组列表(键值)。map()遍历列表中的元素,并将lambda x:[::-1]应用到每个元素(元组)以反转它,因此每个元组在从map中分离出来的新列表中成为(value, key)。最后,dict()从新的列表中发出命令。

#15


1  

Adding an in-place solution:

添加一个就地解决方案:

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

In Python3, it is critical that you use list(d.keys()) because dict.keys returns a view of the keys. If you are using Python2, d.keys() is enough.

在Python3中,使用list(.keys())是非常重要的,因为dict.keys返回键的视图。如果使用Python2, d.keys()就足够了。