在python中复制2D数组

enxuqcxy  于 2023-03-04  发布在  Python
关注(0)|答案(2)|浏览(153)

我尝试在python中将一个2D数组复制到另一个2D数组,然后更改副本,而不更改任何其他2D数组,这些数组是原始2D数组的副本,它们的行为相当奇怪。当我第一次需要将2D数组复制到其他2D数组时,咨询stackoverflow时,提示我使用副本()和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))

这个程序让slot1、slot2和slot3复制r1二维数组,然后用rotor类的ring_setting_down函数修改slot1。运行这个程序时,我希望得到slot1、slot2和slot3二维数组,并在修改slot1之前输出这三个数组中的第一个数组,然后再次输出这三个二维数组中的第一个数组。预期输出如下:

[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]

这是相当令人困惑的,因为测试打印(非常专业,我知道)暗示if语句ring_setting_down()的唯一部分是改变slot1的那一部分,而slot2和slot3也不知何故在这个过程中被改变了。将set_rotor()函数中的copy.copy()语句替换为copy.deepcopy()语句似乎给出了相同的结果。
有没有人知道这里发生了什么,以及我如何修改这段代码以获得预期的输出?

hivapdat

hivapdat1#

你好像有两个问题:1)应该使用copy.deepcopy 2)问题似乎出在下面几行:

if sn == s1:
                slot1 = slotn
                self.s1=sn
            if sn == s2:
                slot2=slotn
                self.s2=sn
            if sn == s3:
                slot3=slotn
                self.s3=sn

这段代码将使slot1、slot2和slot3成为彼此的所有别名,因为您使用1、1和1调用set_rotor()。sn的值每次都等于s1、s2和s3,因此它将slot1、slot2和slot3设置为slotn的**相同 * 列表,循环运行三次。
至于解决方案:摆脱循环似乎不是什么大问题,你可以这样做:

slot1 = copy.deepcopy(rotors[s1-1])
self.s1=s1
slot2 = copy.deepcopy(rotors[s2-1])
self.s2=s2
slot3 = copy.deepcopy(rotors[s3-1])
self.s3=s3

如果保持循环很重要因为你有更多的值,

ars1skjm

ars1skjm2#

试着举出一个最简单的例子,以便将来更容易回答。
但是,您似乎应该使用copy.deepcopy()而不是copy.copy()来修复您的问题([copy.deepcopy(rotors[sn-1]) for sn in slots]

相关问题