我收到一个字典作为输入,希望返回一个新的字典,其键将是输入值,值将是相应的输入键。值是唯一的。
例如,假设我的输入是:
a = dict()
a['one']=1
a['two']=2
我希望我的输出结果是:
{1: 'one', 2: 'two'}
为了澄清,我希望我的结果与以下内容等效:res = dict()
res[1] = 'one'
res[2] = 'two'
有没有简洁的Pythonic方式可以实现这个?
我收到一个字典作为输入,希望返回一个新的字典,其键将是输入值,值将是相应的输入键。值是唯一的。
例如,假设我的输入是:
a = dict()
a['one']=1
a['two']=2
我希望我的输出结果是:
{1: 'one', 2: 'two'}
为了澄清,我希望我的结果与以下内容等效:res = dict()
res[1] = 'one'
res[2] = 'two'
有没有简洁的Pythonic方式可以实现这个?
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())
[
和]
。列表推导式不需要[
和]
吗? - Trevor Boyd Smithnew_dict = dict(zip(my_dict.values(), my_dict.keys()))
.values()
和.keys()
是支持dict
的视图,而zip
是一个惰性迭代器;除了所需的新dict
之外,不会产生额外的副本。如果您仍在使用Python 2,则可以使用.itervalues()
和.iterkeys()
(或者完全省略.keys()
,因为dict
已经是它们的键的可迭代对象),并使用itertools.izip
而不是zip
来避免临时变量(例如,dict(itertools.izip(my_dict.itervalues(), my_dict))
将不涉及任何有意义的临时内存开销)。 - ShadowRanger从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'}
你可以使用字典推导式:
res = {v: k for k, v in a.items()}
res = {v: k for k, v in a.iteritems()}
编辑:对于Python 3,请使用a.items()
而不是a.iteritems()
。关于它们之间的区别的讨论可以在SO上的iteritems in Python找到。
In [1]: my_dict = {'x':1, 'y':2, 'z':3}
In [2]: dict((value, key) for key, value in my_dict.items())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
当前主要答案假设值是唯一的,但并非总是如此。如果值不唯一怎么办?您将会失去信息!例如:
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
def reverse_non_unique_mapping(d):
dinv = {}
for k, v in d.items():
if v in dinv:
dinv[v].append(k)
else:
dinv[v] = [k]
return dinv
你可以尝试:
d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.items())
d2
{'two': 2, 'one': 1}
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]
是有效值,但无法作为键使用。请查看此讨论线程以了解更多信息。
res = dict(zip(a.values(), a.keys()))
扩展 Ilya Prokin 的回答 的另一种方法是实际使用 reversed
函数。
dict(map(reversed, my_dict.items()))
本质上,你的字典通过迭代(使用.items()
)进行操作,其中每个项目都是键/值对,这些项目被reversed
函数交换。当传递给dict
构造函数时,它将它们转换为值/键对,这就是你想要的。
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}