Albert gonzal
Albert gonzal

Reputation: 23

Rotating a matrix counter-clockwise changes the original as well

So I currently have a function to rotate a matrix counter-clockwise, the list is always a square grid:

def rotate(m: List[List[int]]) -> None:
temp = m.copy()

if len(m) > 1:   
    for x in range(len(m)):
        for y in range(len(m)):
            temp[len(m)-1-y][x] = m[x][y]

m = temp.copy()

I've traced this function repeatedly and to my knowledge it should be working. The problem is that for some reason every change to temp affects the original list. For example,

ORIGINAL =

[[1, 2, 3], 

[4, 5, 6], 

[7, 8, 9]]

WHAT SHOULD OUTPUT = 

[[3, 6, 9], 

[2, 5, 8], 

[1, 4, 7]]

WHAT ACTUALLY OUTPUTS = 

[[3, 6, 1], 

[2, 5, 2], 

[1, 2, 1]

I am on python ver 3.7.0 and have tried slipicing instead of copying the string too but the same thing happens. Anyone know why?

Upvotes: 2

Views: 164

Answers (2)

gotnull
gotnull

Reputation: 27214

import copy

def rotate(m: [[int]]):
    temp = copy.deepcopy(m)
    if len(m) > 1:
        for x in range(len(m)):
            for y in range(len(m)):
                temp[len(m)-1-y][x] = m[x][y]
    return temp

So:

rotate([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

Output:

[[3, 6, 9],
 [2, 5, 8],
 [1, 4, 7]]

Example: https://onlinegdb.com/ryGU1jD6X

Upvotes: 0

blhsing
blhsing

Reputation: 106445

Since every item in the m list is a reference to a sublist, when you make a copy of the m list by calling m.copy(), it is only copying the references of the sublists without creating new copies of the sublists, which is why every change to the temp list is reflected on the original m list.

You should use copy.deepcopy() instead to make copies of the sublists as well:

from copy import deepcopy
def rotate(m):
    temp = deepcopy(m)
    if len(m) > 1:
        for x in range(len(m)):
            for y in range(len(m)):
                temp[len(m)-1-y][x] = m[x][y]
    return temp

so that:

rotate([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

returns:

[[3, 6, 9],
 [2, 5, 8],
 [1, 4, 7]]

Alternatively, you can implement the same matrix rotation by zipping the list of lists and reversing it:

def rotate(m):
    return list(zip(*m))[::-1]

Upvotes: 3

Related Questions