当值不唯一时,转换python字典中的值和键

Transpose values and key in python dictionary when values are not unique

本问题已经有最佳答案,请猛点这里访问。

我想在Python字典中将键改为值,但原始字典中的值不是唯一的。

以下是我的资料:

1
year_person = {2000: ‘Linda’, 2001: ‘Ron’, 2002: ‘Bruce’, 2003: ‘Linda’, 2004: ‘Bruce’, 2005 ‘Gary’, 2006: ‘Linda’}

这就是我要将其更改为:

1
person_year = {‘Linda’: 2000, ‘Ron’: 2001, ‘Bruce’: 2002, ‘Linda’, 2003: ‘Bruce’, 2004 ‘Gary’, 2005: ‘Linda’: 2006}

当我试图用for循环转换它时,我只为每个人得到一对匹配的。


您也可以使用默认dict:

1
2
3
4
5
6
7
8
9
year_person = {2000: 'Linda', 2001: 'Ron', 2002: 'Bruce', 2003: 'Linda', 2004: 'Bruce', 2005: 'Gary', 2006: 'Linda'}

from collections import defaultdict
d = defaultdict(list)
for k, v in year_person.items():
    d[v].append(k)

print dict(d)
>>> {'Bruce': [2002, 2004], 'Linda': [2000, 2003, 2006], 'Ron': [2001], 'Gary': [2005]}


只需展示当前答案中可能缺少的一些其他选项和信息:

如果您确信您的值是唯一的,因此可以成为键,那么最简单的方法是听写理解:

1
2
year_person = {2000: 'Linda', 2001: 'Ron', 2002: 'Bruce', 2003: 'Linda', 2004: 'Bruce', 2005: 'Gary', 2006: 'Linda'}
person_year = {key: value for (value, key) in year_person.items()}

当然,在您的情况下,它们不是,因此这不起作用(因为它只给出最后找到的值):

1
person_year = {'Bruce': 2004, 'Linda': 2006, 'Ron': 2001, 'Gary': 2005}

相反,我们可以在dict comp中使用嵌套的list comp:

1
{key: [value for value, check_key in year_person.items() if check_key==key] for key in year_person.values()}

给我们:

1
{'Bruce': [2002, 2004], 'Linda': [2000, 2003, 2006], 'Ron': [2001], 'Gary': [2005]}

这是可行的,但由于必须循环整个字典中的每个条目,因此效率不高。一个更好的解决方案是艾伦给出的defaultdict解决方案,它只需要一个循环。


在这里,defaultdict是不必要的,把它作为一个列表理解来做会牺牲可读性(尽管通常情况并非如此)。除非分析表明这确实是一个瓶颈,否则我将按如下方式进行操作:

1
2
3
4
5
def invert_to_lists(dct):
    inverted_dict = {}
    for key in dct:
        inverted_dict.setdefault(dct[key], []).append(key)
    return inverted_dict

defaultdict是另一个并发症。在这种情况下,使用setdefault是可以的,因为它只需要打印一次。在完成导入和实例化defaultdict的操作后,您将输入的不仅仅是对setdefault进行一次调用。


你不想实现的在技术上是不可行的。字典的键不能重复,因为如果是这样,则不能用键唯一索引字典。

您可以做的是创建一个(键、值)对的字典,其中value是具有相同键的所有项的列表。为了实现它,你可以做如下的事情

1
2
3
4
5
6
>>> person_year={}
>>> [person_year.setdefault(v,[]).append(k) for (k,v) in year_person.iteritems()]
[None, None, None, None, None, None, None]
>>> person_year
{'Bruce': [2002, 2004], 'Linda': [2000, 2003, 2006], 'Ron': [2001], 'Gary': [2005]}
>>>

注意,如果您只对键值对感兴趣,而不是对本身的字典感兴趣,那么您可以将其作为元组列表存储,如下所示

1
2
3
>>> [(v,k) for k,v in year_person.iteritems()]
[('Linda', 2000), ('Ron', 2001), ('Bruce', 2002), ('Linda', 2003), ('Bruce', 2004), ('Gary', 2005), ('Linda', 2006)]
>>>