当值不唯一时,在python字典中转置值和键

use*_*698 2 python dictionary

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

这是我有的:

year_person = {2000: ‘Linda’, 2001: ‘Ron’, 2002: ‘Bruce’, 2003: ‘Linda’, 2004: ‘Bruce’, 2005 ‘Gary’, 2006: ‘Linda’}
Run Code Online (Sandbox Code Playgroud)

这就是我想要改为:

person_year = {‘Linda’: 2000, ‘Ron’: 2001, ‘Bruce’: 2002, ‘Linda’, 2003: ‘Bruce’, 2004 ‘Gary’, 2005: ‘Linda’: 2006}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用for循环转换它时,我每个人只有一对匹配.

ala*_*lan 8

您也可以使用defaultdict执行此操作:

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

  • 如果要使用`defaultdict`,当实现它的函数返回时,它应该转换为常规`dict`.`defaultdict`具有令人讨厌的属性,即隐式将错过的属性命中转换为插入.也就是说,当它不是你想要的时候会产生错误. (3认同)
  • 这是说明潜在问题的不完全透明的方式. (3认同)

Gar*_*tty 5

只是为了提供当前答案中可能缺少的一些其他选项和信息:

如果你确定你的值是唯一的,因此可以成为键,最简单的方法是字典理解:

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

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

person_year = {'Bruce': 2004, 'Linda': 2006, 'Ron': 2001, 'Gary': 2005}
Run Code Online (Sandbox Code Playgroud)

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

{key: [value for value, check_key in year_person.items() if check_key==key] for key in year_person.values()}
Run Code Online (Sandbox Code Playgroud)

给我们:

{'Bruce': [2002, 2004], 'Linda': [2000, 2003, 2006], 'Ron': [2001], 'Gary': [2005]}
Run Code Online (Sandbox Code Playgroud)

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


Abh*_*jit 3

您不想实现的目标在技术上是不可行的。字典的键不能重复,因为如果重复,则无法使用键对字典进行唯一索引。

您可以做的是创建一个(键,值)对的字典,其中值是具有相同键的所有项目的列表。要实现它,您可以执行以下操作

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

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

>>> [(v,k) for k,v in year_person.iteritems()]
[('Linda', 2000), ('Ron', 2001), ('Bruce', 2002), ('Linda', 2003), ('Bruce', 2004), ('Gary', 2005), ('Linda', 2006)]
>>>
Run Code Online (Sandbox Code Playgroud)