I've maid an algorithm that reverse the diagonals of an array. I'm trying to copy the list a
to b
immutable.
I tried to use "slices" (b = a[:]
), list comprehension and b = a.copy()
but the only one that worked was b = copy.deepcopy(a)
. Are there other ways to get the copy?
import copy
a = [[1,2,3],[4,5,6],[7,8,9]]
b = copy.deepcopy(a)
d = b
c = []
h = len(a[0])-1
x_ptrocar = []
for i in range(len(a)-1):
if i == h:
break
else:
x_ptrocar.extend([[i,i,h,h],[i,h,h,i],[h,h,i,i],[h,i,i,h]])
h -=1
for l in range(len(x_ptrocar)):
for m in range(0,4):
y_original = x_ptrocar[l][3]
y_ptrocar = x_ptrocar[l][1]
x_original = x_ptrocar[l][2]
x_ptrocarr = x_ptrocar[l][0]
a[x_original][y_original]=b[x_ptrocarr][y_ptrocar]
print(a)
I expect the output of [[1,2,3],[4,5,6],[7,8,9]]
to be [[9,2,7], [4,5,6],[3,8,1]]
, and it's working for copy.deepcopy
, but not for any other method I can find.
copy.deepcopy
is overkill for this, pulling in a module and adding function overhead. Since you have a list of lists, making a copy of the outer list with b = a[:]
isn't sufficient because the inner lists in both a
and b
point to identical objects.
You can use a list comprehension as follows:
b = [x[:] for x in a]
This takes a slice of each list in a
, creating a new copy of each sublist without aliasing.
Incidentally, the logic can be simplified somewhat--walk towards the center of the matrix, swapping the top-left/bottom-right and top-right/bottom-left cells along the way:
def reverse_diagonals(m):
m = [x[:] for x in m]
for i in range(len(m) // 2):
m[i][i], m[-i-1][-i-1] = m[-i-1][-i-1], m[i][i]
m[i][-i-1], m[-i-1][i] = m[-i-1][i], m[i][-i-1]
return m
This assumes a nxn matrix.