【问题标题】:Python reverse / inverse a mapping (but with multiple values for each key)Python反向/反向映射(但每个键有多个值)
【发布时间】:2015-06-20 10:43:53
【问题描述】:

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

Python reverse / invert a mapping

给定这样的字典:

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

如何反转这个字典来得到:

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

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

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

【问题讨论】:

  • map 是关键字,请勿用作字典名称。
  • 结果我把措辞改成了dict
  • @KevinLee, dict 也是一个关键字 :-))
  • @ForceBru 谢谢我对 Python 的思考还不够。

标签: python dictionary mapping inverse


【解决方案1】:

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() 方法,因为它会返回一个键值对列表。我们不想构造一个列表只是为了迭代和构造一个新字典。这就是为什么我们更喜欢iteritems(),它返回一个迭代器对象,该对象在迭代时给出一个键值对。

注意: Python 3.x 的items 的实际等效项是Python 2.x 的viewitems 方法,它返回一个视图对象。在官方文档here 中阅读有关视图对象的更多信息。


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

Python 2.x 中iter* 函数和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

【讨论】:

    【解决方案2】:
    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'}

    注意: 字典是一个 unordored 数据结构,因此结果可能不会按照您想要的顺序排列。

    【讨论】:

    • 感谢无序提醒,我最终使用库 natsort 对我的字典进行排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 2020-10-03
    相关资源
    最近更新 更多