You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python复制列表后函数仍修改原列表问题求助

问题:复制列表传入函数后原列表被意外改写

我编写了一个将对象列表转换为字符串列表以写入JSON文件的函数,复制原列表传入该函数后,原列表仍被意外改写。预期columns[0][0]应为原Stone对象的内存地址,但实际输出为字符串"O";注释save(arr)能得到预期结果,但无法保存JSON。检查发现arr与columns的id不同,但原列表还是被修改了。

代码示例:

import json

# 假设Stone是自定义类
class Stone:
    def __init__(self, char):
        self.Char = char

columns = [
            [Stone("O"),Stone("O")],
            [],
            [],
            [],
            [],
            [Stone("X"),Stone("X"),Stone("X"),Stone("X"),Stone("X")],
            [],
            [Stone("X"),Stone("X"),Stone("X")],
            [],
            [],
            [],
            [Stone("O"),Stone("O"),Stone("O"),Stone("O"),Stone("O")],
            [Stone("X"),Stone("X"),Stone("X"),Stone("X"),Stone("X")],
            [],
            [],
            [],
            [Stone("O"),Stone("O"),Stone("O")],
            [],
            [Stone("O"),Stone("O"),Stone("O"),Stone("O"),Stone("O"),],
            [],
            [],
            [],
            [],
            [Stone("X"),Stone("X")]
    ]

def save(array):
        i = 0
        j = 0
        print("Saving....")
        while i < len(array):
            while j < len(array[i]):
                if array[i][j].Char == "O":
                    array[i][j] = "O"
                elif array[i][j].Char == "X":
                    array[i][j] = "X"
                else:
                    continue
                j+=1
            i+=1
            j=0
        print("Saved!")
        array = json.dumps(array)
        jsonFile = open("save.json", "w")
        jsonFile.write(array)
        jsonFile.close()

arr = columns.copy()
save(arr)
print(columns[0][0])

问题原因

columns.copy()是浅拷贝,它只会复制外层列表的结构,但里面的子列表(比如columns[0])还是和原列表共享同一个引用。当你在save函数里修改array[i][j]时,实际上是直接修改了子列表中的元素,而这些子列表和columns里的子列表是同一个对象,所以原列表的元素也会被同步修改。

解决方案

方案1:使用深拷贝

导入copy模块,用deepcopy递归复制所有嵌套对象,这样新列表和原列表完全独立,修改不会影响原列表:

import copy

# ... 其他代码不变 ...

arr = copy.deepcopy(columns)
save(arr)
print(columns[0][0])  # 输出原Stone对象

方案2:修改函数,生成新列表而非修改原列表

重构save函数,创建一个新的列表存储转换后的结果,避免直接修改传入的列表(更符合无副作用的函数设计):

def save(array):
    print("Saving....")
    # 创建新列表,避免修改原数据
    new_array = []
    for sublist in array:
        new_sublist = []
        for item in sublist:
            if item.Char == "O":
                new_sublist.append("O")
            elif item.Char == "X":
                new_sublist.append("X")
            else:
                new_sublist.append(item)
        new_array.append(new_sublist)
    print("Saved!")
    # 序列化新列表
    json_str = json.dumps(new_array)
    with open("save.json", "w") as jsonFile:
        jsonFile.write(json_str)

# 这里即使使用浅拷贝也不会影响原列表
arr = columns.copy()
save(arr)
print(columns[0][0])  # 输出原Stone对象

另外,代码里的while循环可以换成更简洁的for循环,可读性更高;文件操作推荐用with语句,自动关闭文件,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:52:57