英文:
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
这段代码会导致slot1
、slot2
和slot3
都成为彼此的别名,因为你在set_rotors()
中传递了1、1和1。每次循环运行时,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
如果保留循环很重要,因为你有更多的值,
英文:
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,
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论