在字典中交换键和值的改进方法?

3
我已经阅读了两个关于在字典中交换键和值的问题:Python:最佳方法交换字典中的键和值?如何在字典中交换键和值?
推荐的最佳方法是:
dict((v,k) for k,v in d.items())

然而,如果像这样的字典:
d = {"one":1, "two":2, "a":1}

该方法获取交换后的字典:

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

项目(1:'a')丢失了。那么我该如何获得这样的字典{1:('one','a'),2:'two'}?谢谢。
4个回答

4
这是一种做法:
In [101]: d = {"one":1, "two":2, "a":1}

In [102]: answer = collections.defaultdict(list)

In [103]: for k,v in d.iteritems():
   .....:     answer[v].append(k)

   .....:     

In [104]: answer
Out[104]: defaultdict(<type 'list'>, {1: ['a', 'one'], 2: ['two']})

In [105]: dict(answer)
Out[105]: {1: ['a', 'one'], 2: ['two']}

In [106]: dict((k, tuple(v)) for k,v in answer.iteritems())
Out[106]: {1: ('a', 'one'), 2: ('two',)}

如果你真的想要一行代码(我强烈不建议这样做 - 它非常低效):
In [110]: d
Out[110]: {'a': 1, 'one': 1, 'two': 2}

In [111]: dict((v, tuple([key for key in d if d[key]==v])) for k,v in d.iteritems())
Out[111]: {1: ('a', 'one'), 2: ('two',)}

希望这能帮到您。


1
@AshwiniChaudhary:非常感谢:)。巧合的是,我今天早些时候刚刚获得了那个徽章。 - inspectorG4dget

4
你可以使用dict.setdefault()方法:
In [6]: dd={}

In [7]: for x,y in d.items():
   ...:     dd.setdefault(y,[]).append(x)
   ...:     

In [8]: dd
Out[8]: {1: ['a', 'one'], 2: ['two']}

或者您也可以使用defaultdict()

In [1]: from collections import defaultdict

In [2]: d = {"one":1, "two":2, "a":1}

In [3]: dd=defaultdict(list)

In [4]: for x,y in d.items():
   ...:     dd[y].append(x)
   ...:     

In [5]: dd
Out[5]: defaultdict(<type 'list'>, {1: ['a', 'one'], 2: ['two']})

1
我们刚才是不是同时发布了这个?(惊呆了) - inspectorG4dget
@RohitJain:在这里获取Windows安装说明(http://ipython.org/ipython-doc/stable/install/install.html) - inspectorG4dget
@RohitJain IPython网站建议Windows用户使用以下链接:http://sourceforge.net/projects/console/ - Ashwini Chaudhary
在编程中,“setdefault()”比“defaultdict”更受我欢迎,因为它是内置API的一部分。 - acjay
1
@acjohnson55 基于 setdefault() 的解决方案也比 defaultdict() 更快。 - Ashwini Chaudhary
显示剩余9条评论

2
d = {"one":1, "two":2, "a":1}
a = {}
for k,v in d.iteritems():
    a.setdefault(v, []).append(k)

如果必须是一行代码:
import itertools as it
import operator as op

a = {k:tuple(b[0] for b in v) for k,v in it.groupby(sorted(d.items(), key=op.itemgetter(1)), key=op.itemgetter(1))}

0

我不确定是否有一行代码可以解决,但这个方法可行:

old = {"one": 1, "two": 2, "a": 1}
new = {}

for key, val in old.iteritems():
    new[val] = new.get(val, []) + [key]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接