交换字典键和值仅适用于3个键值对字典

时间:2020-10-25 17:43:46

标签: python python-3.x

这是应该交换字典键和值的函数。 {'a': 3}应该成为{3: 'a'}

def change_keys_values(d):
    for key in d:
        value = d[key]
        del d[key]
        d[value] = key
     
    return d

我意识到此功能不起作用,因为我在迭代过程中更改了字典键。这是我得到的错误:“在迭代过程中更改了字典键”。但是,我没有在三个键值对字典上收到此错误。因此,尽管{'a': 3, 't': 8, 'r': 2, 'z': 44, 'u': 1, 'b': 4}导致上述错误,但{'a': 3, 't': 8, 'r': 2}得到解决而没有任何问题。我正在使用python3。是什么原因造成的?

3 个答案:

答案 0 :(得分:2)

您绝不能在dictionary内修改loop。原因是字典的执行方式。

哈希表

基本上,当您创建字典时,每一项都使用键的哈希值编制索引。

字典实施稀疏

另一个实现细节涉及字典以稀疏方式实现的事实。即,当您创建字典时,内存中有空的地方(称为存储桶)。当您在字典中添加或删除元素时,它可能会达到一个阈值,在该阈值中将重新评估字典的键哈希值,从而改变索引。

粗略地说,这两点是您所观察到的问题背后的原因。

道德点:切勿在任何循环中修改字典。

以下是执行所需操作的简单代码:

def change_keys_values(d):
    new_dict = {value: key for key, value in d.items()}
    return new_dict

答案 1 :(得分:1)

您需要验证值是唯一的,之后没问题:) 但是请确保在解析字典时不要更改字典。否则,您可能会遇到一个已经更改的索引,该索引将被解释两次甚至更多。我建议制作一个新变量(副本):

def invert(dict_: dict) -> dict:
    if list(set(dict_.values())) == list(dict_.values()):  # evaluates if "inverting key:value" is possible (if keys are unique)
        return {b: a for a, b in dict_.items()}
    else:
        raise ValueError("Dictionary values contain duplicates. Inversion not possible!")


print(invert({"a": 1, "b": 2, "c": 3, "d": 4}))  # works

print(invert({"a": 1, "b": 2, "c": 3, "d": 3}))  # fails

答案 2 :(得分:0)

要解决您的问题,只需遍历副本,而不要遍历原始的dict

import copy

def change_keys_values(d):
    for key in copy.deepcopy(d):
        value = d[key]
        del d[key]
        d[value] = key

    return d

然后使用zip的更好选择是:

def change_keys_values(d):
    a, b = zip(*d.items())
    d = dict(list(zip(b,a)))
    return d