Reputation: 23
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
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
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