如何在保留字典顺序的情况下重命名键(Python 3.7+)?

11

我有一个字典,其值如下:

{"a": 1, "b": 2, "c": 3}

我想将键 b 重命名为 B,而不会使其失去它的第二位置。在 Python 3.7 及更高版本中,字典保留插入顺序,因此可以依赖键的顺序,并且可能有意义。我要的最终结果是:

{"a": 1, "B": 2, "c": 3}

明显的代码是运行以下命令:
>>> dictionary["B"] = dictionary.pop("b")
{'a': 1, 'c': 3, 'B': 2}

然而,这种方法不能按照所需的顺序进行。


@RaySteam 是的,最好这样。 - Flimm
1
这个回答解决了你的问题吗?在不失顺序的情况下更改OrderedDict中的键 - Riccardo Bucco
@RaySteam 我正在修改一个JSON文件,我想要漂亮的差异比较结果,但是请回答者们不要回答JSON部分,我只想知道这个特定问题的答案,因为我可以看到自己在其他情况下也需要知道这个答案。 - Flimm
@RaySteam 不,链接的问题是关于OrderedDict而不是字典。 - Flimm
4
字典现在保留插入顺序,但如果你想在特定索引处插入或删除元素,它们仍然不是一个好的数据结构选择。因此,要么选择不同的数据结构,要么接受像重新构建整个字典这样的O(n)解决方案。 - Chris_Rands
显示剩余8条评论
4个回答

6
foo = {'c': 2, 'b': 4, 'J': 7}
foo = {key if key != 'b' else 'B': value for key, value in foo.items()}
foo
Out[7]: {'c': 2, 'B': 4, 'J': 7}

1
这会创建一个新的字典,而不是直接修改原有的字典。 - Flimm

3

这个解决方案会直接修改字典d。如果性能不是问题,你可以按照以下方式操作:

d = {"a": 1, "b": 2, "c": 3, "d": 4}
replacement = {"b": "B"}

for k, v in list(d.items()):
    d[replacement.get(k, k)] = d.pop(k)

print(d)

输出:

{'a': 1, 'B': 2, 'c': 3, 'd': 4}

请注意,上述解决方案适用于替换任何数量的键。另外需要注意的是,您需要迭代 d.items() 的副本(使用 list(d.items())),因为您不应在修改字典键时迭代字典。


@wklchris 你所提到的错误可以通过循环遍历 list(d.items()) 来解决,参见编辑。 - Flimm

2
作为现有答案的一种变体,也适用于多次替换,您可以定义另一个字典,显示要用其他键替换的键:
>>> d = {"a": 1, "b": 2, "c": 3}
>>> repl = {"b": "B"}
>>> {repl.get(k, k): d[k] for k in d}
{'a': 1, 'B': 2, 'c': 3}

当然,这仍然会创建一个新的字典而不是更新现有的字典,因此需要O(n),但至少它只需要一次来更新所有需要更新的键。

1
dict1 = {"a": 1, "b": 2, "c": 3}
dict2 = dict()

for key in dict1:
    if key == 'b':
        dict2[key.upper()] = dict1[key]
    else:
        dict2[key] = dict1[key]

dict1 = dict2 #if you want to have it in original dict

if语句中,您可以设置任何想要的值。


2
这将创建一个新的字典,而不是直接修改现有的字典。 - Riccardo Bucco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接