Python 反转/反转映射(但每个键有多个值)
Python reverse / inverse a mapping (but with multiple values for each key)
这确实是这个问题的变体,但不是重复的:
Python reverse / invert a mapping
给定一个像这样的字典:
mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }
如何反转这个字典得到:
inv_mydict = { 'b':'a', 'c':'a', 'e':'d', 'f':'d' }
请注意,值在每个键下的跨度是唯一的。
注意:我之前有语法map = ...
和dict = ...
提醒不要按原样使用map
和dict
内置函数,请参阅下面的优秀评论和答案:)
TL;DR
像这样使用字典理解
>>> 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'}
上面看到的字典理解在功能上等同于以下填充空字典的循环结构
>>> 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
函数。因此,除非您知道自己在做什么,否则不要将其用作变量名。
其他类似的方法
Python 3.x
你可以像这样使用dict.items
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
我们在这里使用 items()
方法,它会从字典中创建一个视图对象,它会在迭代时给出键值对。所以我们只是迭代它并使用逆映射构造一个新字典。
Python 2.x
你可以这样使用dict.iteritems
>>> {value: key for key, values in my_map.iteritems() for value in values}
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}
我们不喜欢 2.x 中的 items()
方法,因为它将 return 键值对列表。我们不想构造一个列表只是为了迭代和构造一个新的字典。这就是为什么我们更喜欢 iteritems()
,它 return 是一个迭代器对象,它在迭代时给出一个键值对。
注意: Python 3.x 的 items
的实际等价物是 Python 2.x的 viewitems
method, which returns a view object. Read more about the view object in the official documentation, here.
iter*
与 Python 2.x
中的 view*
方法
iter*
函数与 Python 2.x 中的 view*
函数的主要区别在于,视图对象反映字典的当前状态。例如,
>>> d = {1: 2}
>>> iter_items = d.iteritems()
>>> view_items = d.viewitems()
现在我们向字典中添加一个新元素
>>> d[2] = 3
如果您尝试检查 (2, 3)
(键值对)是否在 iter_items
中,它会抛出错误
>>> (2, 3) in iter_items
Traceback (most recent call last):
File "<input>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
但视图对象将反映字典的当前状态。所以,它会工作正常
>>> (2, 3) in view_items
True
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'}
注意:字典是一种无序数据结构,因此结果可能不会按您希望的那样排序。
这确实是这个问题的变体,但不是重复的:
Python reverse / invert a mapping
给定一个像这样的字典:
mydict= { 'a': ['b', 'c'], 'd': ['e', 'f'] }
如何反转这个字典得到:
inv_mydict = { 'b':'a', 'c':'a', 'e':'d', 'f':'d' }
请注意,值在每个键下的跨度是唯一的。
注意:我之前有语法map = ...
和dict = ...
提醒不要按原样使用map
和dict
内置函数,请参阅下面的优秀评论和答案:)
TL;DR
像这样使用字典理解
>>> 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'}
上面看到的字典理解在功能上等同于以下填充空字典的循环结构
>>> 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
函数。因此,除非您知道自己在做什么,否则不要将其用作变量名。
其他类似的方法
Python 3.x
你可以像这样使用dict.items
>>> {value: key for key, values in my_map.items() for value in values}
{'c': 'a', 'f': 'd', 'b': 'a', 'e': 'd'}
我们在这里使用 items()
方法,它会从字典中创建一个视图对象,它会在迭代时给出键值对。所以我们只是迭代它并使用逆映射构造一个新字典。
Python 2.x
你可以这样使用dict.iteritems
>>> {value: key for key, values in my_map.iteritems() for value in values}
{'c': 'a', 'b': 'a', 'e': 'd', 'f': 'd'}
我们不喜欢 2.x 中的 items()
方法,因为它将 return 键值对列表。我们不想构造一个列表只是为了迭代和构造一个新的字典。这就是为什么我们更喜欢 iteritems()
,它 return 是一个迭代器对象,它在迭代时给出一个键值对。
注意: Python 3.x 的 items
的实际等价物是 Python 2.x的 viewitems
method, which returns a view object. Read more about the view object in the official documentation, here.
iter*
与 Python 2.x
中的 view*
方法
iter*
函数与 Python 2.x 中的 view*
函数的主要区别在于,视图对象反映字典的当前状态。例如,
>>> d = {1: 2}
>>> iter_items = d.iteritems()
>>> view_items = d.viewitems()
现在我们向字典中添加一个新元素
>>> d[2] = 3
如果您尝试检查 (2, 3)
(键值对)是否在 iter_items
中,它会抛出错误
>>> (2, 3) in iter_items
Traceback (most recent call last):
File "<input>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
但视图对象将反映字典的当前状态。所以,它会工作正常
>>> (2, 3) in view_items
True
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'}
注意:字典是一种无序数据结构,因此结果可能不会按您希望的那样排序。