就地Python字典逆

时间:2017-12-05 17:18:33

标签: python dictionary swap in-place

我想要查看的任务是否可以解决,是交换字典的键值对(在Python中),使用就地计算,没有其他数据结构(仅限)恒定数量的额外变量)。这似乎是不可能的(在有限的世界中),但我可以听到解决它的建议。

我在python中看到了一些关于就地字典逆的帖子,我发现所有解决方案之间都有一个共同点。 以下字典无法正确反转:

dict = {'b':'a','a':'c','c':123}

原因是,在交换第一个参数时,我们会覆盖“实际值”(值是唯一的,键是唯一的,但不是表示不存在与现有密钥相同的值(

备注:

1)作为示例给出的字典具有可散列值。

2)键/值可以是任何数据类型。不一定是字符串。

我喜欢听到解决它的方法,我已经想到了一个,但只有当我们拥有无限的记忆时,这才有效,这显然不是真的。

修改

1)我的想法是,更改字典,以便在每个键条目的开头添加一定数量的下划线(" _")。下划线的数量是根据键确定的,如果某些键具有X下划线,则我将添加X + 1下划线(max_underscores_of_key_in_prefix + 1)。 要解决密钥中的对象,我将为此创建一个包装类。 我尽力解释我的直觉,但我不确定这是否实用。

2)@Mark Ransom的解决方案完美无缺,但如果有人对问题有其他算法解决方案,我仍然希望听到它! 我将这个问题标记为已解决,因为它已经解决,但同样,其他解决方案非常受欢迎: - )

1 个答案:

答案 0 :(得分:2)

显然,为了实现这一点,密钥和值都必须是可清除的。这意味着您的所有键或值都不能是list。我们可以利用这一点来了解哪些字典元素已经被处理过。

由于您无法同时迭代和修改字典,因此每次交换键/值时都必须重新开始。这使得这非常慢,一个O(n ^ 2)操作。

def invert_dict(d):
    done = False
    while not done:
        done = True
        for key, val in d.items():
            if isinstance(val, list):
                if len(val) > 1:
                    d[key] = [val[1]]
                    val = val[0]
            else:
                del d[key]
            if not isinstance(val, list):
                if val in d:
                    d[val] = [d[val], key]
                else:
                    d[val] = [key]
                done = False
                break
    for key, val in d.items():
        d[key] = val[0]