我尝试在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()语句似乎给出了相同的结果。
有没有人知道这里发生了什么,以及我如何修改这段代码以获得预期的输出?
2条答案
按热度按时间hivapdat1#
你好像有两个问题:1)应该使用copy.deepcopy 2)问题似乎出在下面几行:
这段代码将使slot1、slot2和slot3成为彼此的所有别名,因为您使用1、1和1调用set_rotor()。sn的值每次都等于s1、s2和s3,因此它将slot1、slot2和slot3设置为slotn的**相同 * 列表,循环运行三次。
至于解决方案:摆脱循环似乎不是什么大问题,你可以这样做:
如果保持循环很重要因为你有更多的值,
ars1skjm2#
试着举出一个最简单的例子,以便将来更容易回答。
但是,您似乎应该使用
copy.deepcopy()
而不是copy.copy()
来修复您的问题([copy.deepcopy(rotors[sn-1]) for sn in slots]
)