Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在字典中交换键值对_Python_Python 3.x_Dictionary_Swap_Space Complexity - Fatal编程技术网

Python 在字典中交换键值对

Python 在字典中交换键值对,python,python-3.x,dictionary,swap,space-complexity,Python,Python 3.x,Dictionary,Swap,Space Complexity,我正在寻找交换给定字典的所有键值对的方法 到目前为止,我可以想到一种方法: 例: >>>a = { 0: 'a', 1 : 'b', 2 : 'c' } >>> {value : key for key,value in a.items()} {'a': 0, 'b': 1, 'c' : 2} 要不是这样,我就必须使用额外的空间来声明另一本词典。 我想知道我可以使用哪些方法来交换键值对以提高空间效率 要不是这样,我就必须使用额外的空间来声明另一本词典 因为字

我正在寻找交换给定字典的所有键值对的方法

到目前为止,我可以想到一种方法:

例:

>>>a = { 0: 'a', 1 : 'b', 2 : 'c' }
>>> {value : key for key,value in a.items()}
{'a': 0, 'b': 1, 'c' : 2}
要不是这样,我就必须使用额外的空间来声明另一本词典。
我想知道我可以使用哪些方法来交换键值对以提高空间效率

要不是这样,我就必须使用额外的空间来声明另一本词典

因为字典本质上是一个查找表,所以它在内存中有一种具体的布局方式;密钥被有效地分配,只指向本身没有特殊意义的值。因此,当您想要反转映射时,您不能真正使用现有的结构;相反,您必须从头开始创建新的词典条目。你在问题中使用的词典理解是一个很好的明确的方法

但是,您可以做的是重新使用已有的字典,并在其中添加新键(同时删除旧键):

这会修改同一个字典,因此不会有新字典的开销(可能很少)。请注意,这假设所有值都是唯一的,因此映射可以完全反转,并且键和值集不共享公共值。否则,您将遇到字典大小更改异常或缺少值。您可以通过创建字典键的副本来避免前者(尽管这意味着您现在也要存储一个列表):


最后一点注意:像这样多次修改字典可能会产生一些重新映射的副作用(增加哈希表大小等),但这可能是CPython的实现细节(我不太确定)。

试试这段代码。它在反转键和值之前删除字典中的项

for k, v in a.items():
  del a[k]
  a[v] = k

为了避免@DSM在@poke的回答中指出的特殊情况,我建议始终使用第二本词典。性能完全相同

b = dict()
for k, v in a.items(): # a.iteritems() in python 2
    b[v] = k
    del a[k]
a = b

如前所述,这(1)是否会导致字典大小更改错误,以及(2)在某些情况下不起作用,例如,
a={1:1,2:3,3:2}
?@DSM是的,尽管它在OP的示例中对我有效,但这可能是可能的。不过,您可能需要创建密钥列表的副本。至于(2),是的,对于这个例子,它会中断,但我假设的情况与OP的例子类似,这里的键集和值集是不同的。如果两个值重复或者你有一个不可散列的值怎么办?@padraickenningham嗯,如果两个(或更多)键具有相同的值,那么覆盖将是唯一的方法。一、 猜猜看@PadraicCunningham我没有想到不可破坏的价值场景!任何建议都会很有帮助,这是很重要的,我认为要么出现错误,要么使用defaultdict并为重复的键创建一个值列表,但这样您将使用混合类型作为值。@PadraicCunningham,但同样,我会占用额外的空间
for k, v in a.items():
  del a[k]
  a[v] = k
b = dict()
for k, v in a.items(): # a.iteritems() in python 2
    b[v] = k
    del a[k]
a = b