关于字典:Python反向/反向映射(但每个键有多个值)

Python reverse / inverse a mapping (but with multiple values for each key)

这确实是对这个问题的一个变体,但不是一个副本:

python反转/反转映射

像这样的字典:

mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }

如何将此dict转换为:

江户十一〔一〕号

请注意,每个键下的值范围都是唯一的。

注:我以前有语法map = ...dict = ...提示不要使用mapdict作为内置函数,见下面的精彩评论和答案:)


DR

像这样使用字典理解

1
2
3
>>> my_map = { 'a': ['b', 'c'], 'd': ['e', 'f'] }
>>> {value: key for key in my_map for value in my_map[key]}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}

上面看到的字典理解在功能上相当于下面的循环结构,它填充空字典

1
2
3
4
5
6
7
>>> inv_map = {}
>>> for key in my_map:
...     for value in my_map[key]:
...         inv_map[value] = key
...
>>> inv_map
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}

注意:使用map隐藏了内置的map功能。所以,除非你知道你在做什么,否则不要用它作为变量名。

其他类似的方法

Python3.x

你可以这样使用dict.items

1
2
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}

我们在这里使用items()方法,从字典中创建一个视图对象,在迭代时给出键值对。所以我们只是迭代它,并用逆映射构造一个新的字典。

Python2.x

你可以这样使用dict.iteritems

1
2
>>> {value: key for key, values in my_map.iteritems() for value in values}
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}

我们不喜欢在2.x中使用items()方法,因为它将返回一个键值对列表。我们不想仅仅为了迭代和构造一个新的字典而构造一个列表。这就是为什么我们更喜欢iteritems(),它返回一个迭代器对象,该对象在迭代时给出一个键值对。

注意:python 3.x的items的实际等价物是python 2.x的viewitems方法,它返回一个视图对象。请阅读官方文档中关于视图对象的更多信息。

python 2.x中的iter*view*方法

在python 2.x中,iter*函数和view*函数的主要区别在于,视图对象反映字典的当前状态。例如,

1
2
3
>>> d = {1: 2}
>>> iter_items = d.iteritems()
>>> view_items = d.viewitems()

现在我们在字典中添加一个新元素

1
>>> d[2] = 3

如果您试图检查EDOCX1(键值对)是否在iter_items中,它将抛出一个错误。

1
2
3
4
>>> (2, 3) in iter_items
Traceback (most recent call last):
  File"<input>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

但是视图对象将反映字典的当前状态。所以,它会很好地工作的

1
2
>>> (2, 3) in view_items
True

1
2
3
4
5
6
7
8
mp = { 'a': ['b', 'c'], 'd': ['e', 'f'] }

pm={}
for x in mp.iterkeys():
    for d in mp[x]:
        pm[d]=x

print pm

输出:

{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}

注意:字典是一个无序的数据结构,因此结果可能不会按您希望的那样排序。