在Python中复制2D数组

huangapple go评论65阅读模式
英文:

copying 2D arrays in python

问题

test 1
test 1
test 1
英文:

I'm trying to copy a 2D array to another 2D array in python, then change the copy, without changing any other 2D arrays which are a copy of the original 2D array and they're acting rather strangely. Upon consulting stackoverflow when I first needed to copy 2D arrays into other 2D arrays, I was prompted to use the copy() and deepcopy() operations from the copy library. However, this code is acting rather oddly and I can't seem to figure out why.

This is the code:

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))

This program has slot1, slot2, and slot3 copy the r1 2D array, and then changes slot1 with the ring_setting_down function of the class rotors.
Upon running this, I expected to get the slot1, slot2 and slot3 2D arrays and output the first array in those three, before changing slot1, and then once again outputting the first array within these three 2D arrays.
The expected output would be:

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

however, for some reason, the actual output is:

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

This is rather confusing because the testing prints (very professional, I know) imply the only part of the if statements ring_setting_down() is the one that changes slot1, yet slot2 and slot3 have somehow also been changed in the process. Swapping the copy.copy() statement in the set_rotors() function for a copy.deepcopy() statement seems to give the same result.

Can anyone else figure out what is going on here and how I could modify this code to give me the expected output?

答案1

得分: 0

尝试创建一个最小示例,以便未来更容易回答。

然而,似乎你应该使用copy.deepcopy()而不是copy.copy()来解决你的问题([copy.deepcopy(rotors[sn-1]) for sn in slots]

英文:

Try to produce a minimal example to make it easier to answer in the future.

However, it seems like you should use copy.deepcopy() rather than copy.copy() to fix your issue ([copy.deepcopy(rotors[sn-1]) for sn in slots])

答案2

得分: 0

你似乎有两个问题: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

这段代码会导致slot1slot2slot3都成为彼此的别名,因为你在set_rotors()中传递了1、1和1。每次循环运行时,sn的值都等于s1s2s3,因此它将slot1slot2slot3都设置为相同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

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

英文:

You seem to have two issues: 1) copy.deepcopy should be used. 2) The problem appears to be in the next few lines:

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

This code will make slot1, slot2, and slot3 all aliases of each other because you call set_rotors() with 1, 1, and 1. The value of sn is equal to s1, s2, and s3 every time, so it sets slot1, slot2, and slot3 to the same list of slotn all 3 times the loop runs.

As for a solution: Getting rid of the loop doesn't seem to be too much of an issue. You could just do this:

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

If keeping the loop is important because you have more values,

huangapple
  • 本文由 发表于 2023年2月27日 08:19:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575849.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定