Python:使用字典中的值来交换密钥的最佳方法?

Roe*_*ler 85 python dictionary

我收到一个字典作为输入,并希望返回一个字典,其键将是输入的值,其值将是相应的输入键.价值观是独一无二

例如,说我的输入是:

a = dict()
a['one']=1
a['two']=2
Run Code Online (Sandbox Code Playgroud)

我希望我的输出是:

{1: 'one', 2: 'two'}
Run Code Online (Sandbox Code Playgroud)

为了澄清我希望我的结果等同于以下内容:

res = dict()
res[1] = 'one'
res[2] = 'two'
Run Code Online (Sandbox Code Playgroud)

任何巧妙的Pythonian方式来实现这一目标?

谢谢

lio*_*ori 136

Python 2:

res = dict((v,k) for k,v in a.iteritems())
Run Code Online (Sandbox Code Playgroud)

Python 3(感谢@erik):

res = dict((v,k) for k,v in a.items())
Run Code Online (Sandbox Code Playgroud)

  • 对于Python3,它将是`res = {v:k代表k,v代表a.items()}`. (61认同)
  • 虽然这似乎是正确的,但添加对其工作方式的解释非常好,而不仅仅是代码. (12认同)
  • 如果值不是唯一的怎么办?然后键应该是一个列表...例如:d = {'a':3,'b':2,'c':2} {v:k代表k,v代表d.iteritems()} { 2:'b',3:'a'}应为{2:['b','c'],3:'a'} (4认同)
  • @HananShteingart:OP的问题表明价值是独一无二的.请为您的案例创建一个单独的问题帖子(最好将其链接到其他人). (4认同)

Jav*_*ier 53

new_dict = dict (zip(my_dict.values(),my_dict.keys()))
Run Code Online (Sandbox Code Playgroud)

  • 是否值()和键()保证具有相同的顺序? (4认同)
  • 是的,这个答案遍历了两次dict.sunqiang的答案更适合大字典,因为它只需要一次迭代. (4认同)
  • 是的,来自http://www.python.org/dev/peps/pep-3106/ 该规范意味着 .keys()、.values() 和 .items() 返回项目的顺序是相同的(就像在 Python 2.x 中一样),因为顺序都是从 dict 迭代器派生的(它可能是任意的,但只要不修改 dict 就稳定)。但这个答案需要调用 my_dict 两次(一次用于值,一次用于键)。也许这并不理想。 (2认同)

Sil*_*ost 44

从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'}
Run Code Online (Sandbox Code Playgroud)


sun*_*ang 30

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'}
Run Code Online (Sandbox Code Playgroud)

  • 不是在原始问题中,我只是好奇如果你在原始字典中有重复值然后用这种方法交换键/值会发生什么? (3认同)
  • @Andre Miller:特定键的最后一次出现:dict(((1,3),(1,2)))== {1:2} (2认同)
  • 重复将被最后遇到的欺骗覆盖. (2认同)
  • @Andre Miller:因为d.items()以任意顺序返回项目,所以你得到一个重复值的任意键. (2认同)

Aka*_*all 28

你可以使用dict理解:

res = {v: k for k, v in a.iteritems()}
Run Code Online (Sandbox Code Playgroud)

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


Ala*_*air 18

你可以尝试:

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

请注意,如果你不能"反转"字典

  1. 多个密钥共享相同的值.例如{'one':1,'two':1}.新词典只能有一个带键的项目1.
  2. 一个或多个值是不可用的.例如{'one':[1]}.[1]是有效值,但不是有效密钥.

请参阅python邮件列表中的此主题以获取有关该主题的讨论.


pki*_*kit 14

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

  • @liori:你错了.如果你不修改对values()和keys()的调用之间的dict,那么dict保证它的values()和keys()将在同一个顺序上.文档说明:(阅读"注释"部分:http://docs.python.org/library/stdtypes.html#dict.items)"如果items(),keys(),values(),iteritems( ),iterkeys()和itervalues()被调用而没有对字典的干预修改,列表将直接对应." (19认同)
  • dict不保证其values()和keys()将以相同的顺序返回元素.此外,keys(),values()和zip()返回一个列表,其中迭代器就足够了. (4认同)

bal*_*pha 14

new_dict = dict( (my_dict[k], k) for k in my_dict)
Run Code Online (Sandbox Code Playgroud)

甚至更好,但只适用于Python 3:

new_dict = { my_dict[k]: k for k in my_dict}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,Dict Comprehensions([PEP 274](http://www.python.org/dev/peps/pep-0274/))也适用于Python 2.7. (2认同)

Han*_*art 11

当前的主要答案假定值是唯一的,但并非总是如此.如果值不是唯一的怎么办?你会丢失信息!例如:

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

回报{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
Run Code Online (Sandbox Code Playgroud)

  • 这应该是正确的答案,因为它涵盖了更一般的情况 (2认同)
  • 这次真是万分感谢!我使用其他解决方案丢失了信息。 (2认同)

Sun*_*tel 10

扩展Ilya Prokin的反应的另一种方法是实际使用该reversed功能.

dict(map(reversed, my_dict.items()))
Run Code Online (Sandbox Code Playgroud)

本质上,您的字典是通过(使用.items())迭代的,其中每个项目是键/值对,并且这些项目与reversed函数交换.当它传递给dict构造函数时,它会将它们转换为您想要的值/键对.


小智 6

改善哈维尔答案的建议:

dict(zip(d.values(),d))
Run Code Online (Sandbox Code Playgroud)

而不是d.keys()您只能编写d,因为如果您使用迭代器浏览字典,它将返回相关字典的键。

例如 对于这种行为:

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'
Run Code Online (Sandbox Code Playgroud)


小智 6

可以通过字典理解轻松完成:

{d[i]:i for i in d}
Run Code Online (Sandbox Code Playgroud)