Python反向/反向映射(但每个键具有多个值) [英] Python reverse / inverse a mapping (but with multiple values for each key)
问题描述
这真的是这个问题的一个变体,但不是重复的:
给出一个这样的字典:
mydict = {'a':['b','c'],'d':['e','f']}
如何反转这个dict来获取:
inv_mydict = {'b':'a','c ':'a','e':'d','f':'d'}
每个键。
注意:我以前有语法 map = ...
dict = ...
提醒不要使用地图
和 dict
TL; DR
使用字典理解,像这样
>>> my_map = {'a':['b','c'],'d':['e','f']}
>>> {value:key in my_map for my_map [key]}
{'c':'a','f':'d','b':'a','e' d'}
上面看到的字典理解在功能上相当于填充空字典的以下循环结构
>>> inv_map = {}
/ pre>
>>>>对于my_map中的键值:
... for my_map [key]中的值:
... inv_map [value] = key
...
>>> inv_map
{'c':'a','f':'d','b':'a','e':'d'}
注意使用
map
阴影内置map
功能。所以,不要使用它作为一个变量名,除非你知道你在做什么。
其他类似
Python 3.x
您可以使用
dict.items
,像这样>>> {value:key的键值,my_map.items()中值的值中的值}
{'c':'a','f':'d','b':'a','e ':'d'}
我们使用
items()
方法,这将从字典创建一个视图对象,它将给迭代中的键值对。所以我们只是迭代它,并用反向映射构造一个新的字典。
Python 2.x
您可以使用
dict .iteritems
这样>>> {value:key的键值,my_map.iteritems()中值的值中的值}
{'c':'a','b':'a','e':'d','f ':'d'}
我们不喜欢
items() / code>方法,因为它将返回键值对列表。我们不想仅仅构造一个列表来迭代和构造一个新的字典。这就是为什么我们更喜欢
iteritems()
,它返回一个迭代器对象,它给出迭代中的一个键值对。
注意: Python 3.x的
项目的实际等价物将是Python 2.x的
viewitems
方法,返回一个视图对象。详细了解官方文档中的视图对象,这里。
iter *
vs查看*
Python 2.x中的方法
iter *
函数之间的主要区别和$ 2.c中的视图*
函数是视图对象反映字典的当前状态。例如,>>> d = {1:2}
>>> iter_items = d.iteritems()
>>> view_items = d.viewitems()
现在我们在字典中添加一个新元素
>>> d [2] = 3
如果您尝试检查
(2, 3)
(键值对)位于iter_items
中,会抛出错误>>> (2,3)in iter_items
追溯(最近的最后一次调用):
文件< input>,第1行,< module>
RuntimeError:字典在迭代期间更改大小
但是查看对象将反映当前状态字典。所以,它会正常工作
>>> (2,3)in view_items
True
This is really a variation on this question, but not a duplicate:
Python reverse / inverse a mapping
Given a dictionary like so:
mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }
How can one invert this dict to get:
inv_mydict = { 'b':'a', 'c':'a', 'e':'d', 'f':'d' }
Note that values span uniquely under each key.
Note: I previously had syntax
map = ...
anddict = ...
Reminder not to usemap
anddict
as they are built-in functions, see excellent comments and answers below :)解决方案TL;DR
Use dictionary comprehension, like this
>>> 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'}
The above seen dictionary comprehension is functionally equivalent to the following looping structure which populates an empty dictionary
>>> 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'}
Note: Using
map
shadows the built-inmap
function. So, don't use that as a variable name unless you know what you are doing.
Other similar ways to do the same
Python 3.x
You can use
dict.items
, like this>>> {value: key for key, values in my_map.items() for value in values} {'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
We use
items()
method here, which would create a view object from the dictionary which would give key value pairs on iteration. So we just iterate over it and construct a new dictionary with the inverse mapping.Python 2.x
You can use
dict.iteritems
like this>>> {value: key for key, values in my_map.iteritems() for value in values} {'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}
We don't prefer
items()
method in 2.x, because it will return a list of key-value pairs. We don't want to construct a list just to iterate and construct a new dictionary. That is why we preferiteritems()
, which returns an iterator object which gives a key value pair on iteration.Note: The actual equivalent of Python 3.x's
items
would be Python 2.x'sviewitems
method, which returns a view object. Read more about the view object in the official documentation, here.
iter*
vsview*
methods in Python 2.xThe main difference between
iter*
functions andview*
functions in Python 2.x is that, the view objects reflect the current state of the dictionary. For example,>>> d = {1: 2} >>> iter_items = d.iteritems() >>> view_items = d.viewitems()
now we add a new element to the dictionary
>>> d[2] = 3
If you try to check if
(2, 3)
(key-value pair) is in theiter_items
, it will throw an error>>> (2, 3) in iter_items Traceback (most recent call last): File "<input>", line 1, in <module> RuntimeError: dictionary changed size during iteration
but view object will reflect the current state of the dictionary. So, it will work fine
>>> (2, 3) in view_items True
这篇关于Python反向/反向映射(但每个键具有多个值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!