Python反向/反向映射(但每个键具有多个值) [英] Python reverse / inverse a mapping (but with multiple values for each key)

查看:645
本文介绍了Python反向/反向映射(但每个键具有多个值)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



Python反向/反向映射



给出一个这样的字典:



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 = {} 
>>>>对于my_map中的键值:
... for my_map [key]中的值:
... inv_map [value] = key
...
>>> inv_map
{'c':'a','f':'d','b':'a','e':'d'}
/ pre>

注意使用 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 = ... and dict = ... Reminder not to use map and dict 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-in map 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 prefer iteritems(), 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's viewitems method, which returns a view object. Read more about the view object in the official documentation, here.


iter* vs view* methods in Python 2.x

The main difference between iter* functions and view* 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 the iter_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆