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

Python二维数组复制异常:修改副本致其他副本同步变更

问题分析与解决

问题描述

尝试将二维数组r1复制到slot1、slot2、slot3三个变量中,期望修改slot1时不影响另外两个副本,但实际修改slot1后,slot2和slot3同步变化。已尝试copy.copy()和deepcopy()方法,但问题依旧。

原代码

import copy

r1 = [4,10,12,5,11,6,3,16,21,25,13,19,14,22,24,7,23,20,18,15,0,8,1,17,2,9],[20,22,24,6,0,3,5,15,21,25,1,4,2,10,12,19,7,23,18,11,17,8,13,16,14,9],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[24],[0]
r2 = [0,9,3,10,18,8,17,20,23,1,11,7,22,19,12,2,16,6,25,13,15,24,5,21,14,4],[0,9,15,2,25,22,17,11,5,1,3,10,14,19,24,20,16,6,4,13,7,23,12,8,21,18],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[12],[0]
r3 = [1,3,5,7,9,11,2,15,17,19,23,21,25,13,24,4,8,22,6,0,10,12,20,18,16,14],[19,0,6,1,15,2,18,3,16,4,20,5,21,13,25,7,24,8,23,9,22,11,17,10,14,12],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[3],[0]
r4 = [4,18,14,21,15,25,9,0,24,16,20,8,17,7,23,11,13,5,19,6,10,3,2,12,22,1],[7,25,22,21,0,17,19,13,11,6,20,15,23,16,2,4,9,12,1,18,10,3,24,14,8,5],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[17],[0]
r5 = [21,25,1,17,6,8,19,24,20,15,18,3,13,7,11,23,0,22,12,9,16,14,
5,4,2,10],[16,2,24,11,23,22,4,13,5,19,25,14,18,12,21,9,20,3,10,6,8,0,17,15,7,1],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[7],[0]
#empty slots for the rotors
slot1 = [],[],[],[],[]
slot2 = [],[],[],[],[]
slot3 = [],[],[],[],[]

class rotors:
    def set_rotors(self,s1,s2,s3):
        global slot1
        global slot2
        global slot3

        slots=[s1,s2,s3]
        rotors=[r1,r2,r3,r4,r5]
        for sn in slots:
            slotn= copy.copy(rotors[sn-1])
            if sn == s1:
                slot1 = slotn
                self.s1=sn
            if sn == s2:
                slot2=slotn
                self.s2=sn
            if sn == s3:
                slot3=slotn
                self.s3=sn
                
    def value(self, rotor):
        if rotor == 1:
            #return(alphabet[(slot1[2][signal]-slot1[4][0])%26])
            return(slot1[0])
        elif rotor == 2:
            #return(alphabet[(slot2[2][signal]-slot2[4][0])%26])
            return(slot2[0])
        elif rotor == 3:
            #return(alphabet[(slot3[2][signal]-slot3[4][0])%26])
            return(slot3[0])
        
    def ring_setting_down(self,slot,setting):
        if slot==1:
            for i in range(26):
                slot1[0][i] = (slot1[0][i] - setting)%26
            for i in range(setting):
                slot1[1].insert(25,slot1[1].pop(0))
            print("test 1")
        elif slot==2:
            for i in range(26):
                slot2[0][i] = (slot2[0][i] - setting)%26
            for i in range(setting):
                slot2[1].insert(25,slot2[1].pop(0))
            print("test 2")
        elif slot==3:
            for i in range(26):
                slot3[0][i] = (slot3[0][i] - setting)%26
            for i in range(setting):
                slot3[1].insert(25,slot3[1].pop(0))
            print("test 3")
        
RT=rotors()
RT.set_rotors(1,1,1)
print(RT.value(1))
print(RT.value(2))
print(RT.value(3))
RT.ring_setting_down(1,1)
print(RT.value(1))
print(RT.value(2))
print(RT.value(3))

预期输出

[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
test 1
[3, 9, 11, 4, 10, 5, 2, 15, 20, 24, 12, 18, 13, 21, 23, 6, 22, 19, 17, 14, 25, 7, 0, 16, 1, 8]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]

实际输出

[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
[4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9]
test 1
[3, 9, 11, 4, 10, 5, 2, 15, 20, 24, 12, 18, 13, 21, 23, 6, 22, 19, 17, 14, 25, 7, 0, 16, 1, 8]
[3, 9, 11, 4, 10, 5, 2, 15, 20, 24, 12, 18, 13, 21, 23, 6, 22, 19, 17, 14, 25, 7, 0, 16, 1, 8]
[3, 9, 11, 4, 10, 5, 2, 15, 20, 24, 12, 18, 13, 21, 23, 6, 22, 19, 17, 14, 25, 7, 0, 16, 1, 8]

原因分析

  1. r1的结构问题:r1的定义是用逗号分隔的多个列表,实际是一个元组(Python中逗号分隔的序列默认是元组),元组内的元素是列表(可变对象)。
  2. 浅拷贝的局限性:原代码使用copy.copy()做浅拷贝,仅复制了元组的外壳,元组内的列表并未被复制,只是引用了原r1中的列表对象。因此slot1、slot2、slot3指向的是同一组列表,修改其中一个就会影响所有引用。
  3. 循环逻辑冗余:当s1、s2、s3取值相同时,循环会重复执行三次拷贝,且每次都会触发所有if条件,虽然不影响结果,但逻辑不够严谨。

解决方法

将copy.copy()替换为copy.deepcopy(),深拷贝会递归复制所有层级的对象,包括元组内的列表,确保每个slot都拥有独立的副本。同时优化循环逻辑,避免重复赋值。

修改后的代码

import copy

r1 = [4,10,12,5,11,6,3,16,21,25,13,19,14,22,24,7,23,20,18,15,0,8,1,17,2,9],[20,22,24,6,0,3,5,15,21,25,1,4,2,10,12,19,7,23,18,11,17,8,13,16,14,9],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[24],[0]
r2 = [0,9,3,10,18,8,17,20,23,1,11,7,22,19,12,2,16,6,25,13,15,24,5,21,14,4],[0,9,15,2,25,22,17,11,5,1,3,10,14,19,24,20,16,6,4,13,7,23,12,8,21,18],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[12],[0]
r3 = [1,3,5,7,9,11,2,15,17,19,23,21,25,13,24,4,8,22,6,0,10,12,20,18,16,14],[19,0,6,1,15,2,18,3,16,4,20,5,21,13,25,7,24,8,23,9,22,11,17,10,14,12],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[3],[0]
r4 = [4,18,14,21,15,25,9,0,24,16,20,8,17,7,23,11,13,5,19,6,10,3,2,12,22,1],[7,25,22,21,0,17,19,13,11,6,20,15,23,16,2,4,9,12,1,18,10,3,24,14,8,5],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],[1
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:18:41