Python反向/反向映射(但每个键有多个值)

Python反向/反向映射(但每个键有多个值),python,dictionary,mapping,inverse,Python,Dictionary,Mapping,Inverse,这实际上是这个问题的一个变体,但不是重复: 如果有这样一本字典: mydict={'a':['b','c'],'d':['e','f']} 如何将这句话翻过来得到: inv_mydict={'b':'a','c':'a','e':'d','f':'d'} 请注意,每个键下的值都是唯一的 注意:我以前有过语法map=…和dict=…提醒不要使用map和dict,因为它们是内置函数,请参阅下面的优秀注释和答案:)TL;博士 像这样使用字典理解 >>> my_map = { 'a'

这实际上是这个问题的一个变体,但不是重复:

如果有这样一本字典:

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

如何将这句话翻过来得到:

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

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

注意:我以前有过语法
map=…
dict=…
提醒不要使用
map
dict
,因为它们是内置函数,请参阅下面的优秀注释和答案:)

TL;博士 像这样使用字典理解

>>> 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'}
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
>>> {value: key for key, values in my_map.iteritems() for value in values}
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}

上述词典理解在功能上等同于以下填充空词典的循环结构

>>> 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'}
>>> d[2] = 3
注意:使用
map
隐藏内置函数。所以,除非您知道自己在做什么,否则不要将其用作变量名


其他类似的方法也可以这样做

Python3.x

你可以这样用

>>> 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'}
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
>>> {value: key for key, values in my_map.iteritems() for value in values}
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}
我们在这里使用
items()
方法,它将从字典中创建一个视图对象,在迭代时提供键值对。所以我们只需对它进行迭代,然后用逆映射构造一个新的字典

python2.x

你可以这样用

>>> 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'}
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
>>> {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()
,它返回一个迭代器对象,该对象在迭代时给出一个键值对

注意:Python3.x的
项的实际等价物是Python2.x的方法,它返回一个视图对象。请阅读官方文档中有关view对象的详细信息


iter*
vs
view*
python2.x中的方法 Python 2.x中的
iter*
函数和
view*
函数之间的主要区别在于,视图对象反映字典的当前状态。比如说,

>>> d = {1: 2}
>>> iter_items = d.iteritems()
>>> view_items = d.viewitems()
现在我们向字典中添加一个新元素

>>> 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'}
>>> d[2] = 3
如果您试图检查
(2,3)
(键值对)是否在
iter\u项目中,它将抛出一个错误

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

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


注意:字典是一种无序的数据结构,因此结果可能不会按您希望的顺序排列

map
是一个关键字,不要用作字典名。我改为使用单词来记录result@KevinLee,
dict
也是一个关键字:-)@ForceBru谢谢我对Python的思考不够。谢谢你的无序提醒,我最终使用库
natsort
对我的字典进行排序。