You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中合并含列表的字典时,原字典为何被意外修改?

Why does my original dictionary's list get modified when combining two dictionaries?

Let’s break down what’s happening here—this is a classic case of Python’s shallow vs. deep copying catching folks off guard.

The Root Cause: Shallow Copies Don’t Duplicate Mutable Objects

When you use dict.copy() (like you did with dict_b_copy = d_b.copy()), you’re creating a shallow copy of the dictionary. Here’s what that means:

  • The dictionary itself is a new object, but the values inside it are just references to the original objects.
  • Since lists are mutable (you can change their contents without creating a new list), dict_b_copy["Item1"] points to the exact same list as d_b["Item1"].

So when you run this line:

dict_b_copy[entry_key].append(list_item)

You’re modifying that shared list directly. That’s why the original dict_b ends up with extra elements—you never actually copied the list itself, just the dictionary holding a reference to it.

Why It Works With Unique Keys

When keys are unique, you add a new entry to dict_b_copy like this:

dict_b_copy[entry_key] = dict_a_copy[entry_key]

Since dict_b doesn’t have that key, there’s no shared reference to a list in the original dictionary. You’re just copying the reference from dict_a_copy to the new dictionary, but since you don’t modify that list, the original dict_a and dict_b stay untouched.

Fixing the Problem

You have two solid options to prevent modifying the original dictionaries:

Option 1: Use Deep Copy

Use Python’s copy.deepcopy() to create a full copy of the dictionary and all mutable objects inside it (like lists):

import copy

def combine(d_a, d_b):
    dict_a_copy = copy.deepcopy(d_a)
    dict_b_copy = copy.deepcopy(d_b)
    for entry_key in dict_a_copy:
        if entry_key in dict_b_copy:
            dict_b_copy[entry_key].extend(dict_a_copy[entry_key])
        else:
            dict_b_copy[entry_key] = dict_a_copy[entry_key]
    return dict_b_copy

This ensures every list is a new object, so changes to dict_b_copy won’t affect the original dict_b.

Option 2: Create New Lists When Merging

Instead of modifying the existing list in the shallow copy, create a new list by combining the two:

def combine(d_a, d_b):
    new_dict = d_b.copy()
    for entry_key, items in d_a.items():
        if entry_key in new_dict:
            # Create a new list by combining both lists
            new_dict[entry_key] = new_dict[entry_key] + items
        else:
            new_dict[entry_key] = items.copy()  # Copy the list to avoid referencing dict_a's list
    return new_dict

Here, new_dict[entry_key] = new_dict[entry_key] + items creates a brand new list, so the original list in d_b stays untouched. We also copy the list from d_a when adding new entries to avoid accidentally modifying dict_a later.

Either approach will give you the expected output where dict_a and dict_b remain unchanged, and dict_ab has the combined lists.

内容的提问来源于stack exchange,提问作者Iain Waugh

火山引擎 最新活动