So, I was solving(or rather, looking at the solution haha) a question on Leetcode, and this was a solution to allow you to generate all possible permutations of an array with unique integers.
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
length = len(nums)
results = []
def backtrack(first_char_index):
if first_char_index == length:
# print(nums == nums[:])
results.append(nums)
for index in range(first_char_index, length):
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(first_char_index + 1)
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(0)
return results
So, I was testing out the solution, and I realized that this solution only works if inside the if
condition inside of the backtrack
function, I use results.append(nums[:])
instead of the above results.append(nums)
.
So I initially figured that this was probably because nums[:]
should be used because we need to generate a new copy, but then I had that print statement added before results.append(nums)
, and found that all of the print statements gave me a True
result.
I remember seeing a few solutions with this pattern of having nums[:]
instead of nums
, and would like to ask if anyone could shed light on what exactly does the extra [:] do? I know that it creates a new copy (i.e different object, but same value), but since it has the same value, why does result in a different result?
To illustrate this, the result with an input of [1, 2, 3]
gives
[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
when using nums
, and
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
(the correct answer), when using nums[:]
.
Thanks in advance!
EDIT: For some reason, this question is being recognized to be the same as others that are regarding deep/shallow copy. However, I guess what I'm asking here is that since [:]
results in a new, different object with the same value, and with the fact that the value of nums
and nums[:]
is the same (it prints out to be the altered value), shouldn't it be appending an array with the altered value, instead of the original untouched nums
array?
nums and nums[:] have indeed the same value (that you check using ==), but the are different objects (that you can check using the 'is' keyword). Sequences are mutable, therefore you can change the values they contain without changing the object itself. The [:] simply creates a copy of an existing sequence. This way you have a different object with all the values of the previous one
EDIT: the reason is that, when you append nums to results, nums can still be changed even if it's inside results. Therefore the elements inside results will be changed everytime you change the original nums (in fact in the result all the values are identical). If you create a copy for each element you put in results, instead, the elements will all have different values.