Reputation: 3177
class Solution:
# @param num, a list of integer
# @return a list of lists of integers
def permute(self, num):
self.res = [];
self.dfs(num, 0)
return self.res
def dfs(self, num, level):
if level == len(num):
self.res.append(num)
print(num)
return
for i in range(level, len(num)):
num[i], num[level] = num[level], num[i]
self.dfs(num, level+1)
num[i], num[level] = num[level], num[i]
The above code is used to generate all permutations given a collection of numbers. For example, num = [1, 3] The result will be: [1 3], [3, 1]
But there is a bug for the above code that I don't understand, which is self.res.append(num)
.
If I change it to self.res.append(num[:])
, then the code is correct. Can anyone explain why?
Using self.res.append(num)
, the result is:
[1, 3], [1, 3]
Using self.res.append(num[:])
, the result is:
[1, 3], [3, 1]
Upvotes: 1
Views: 2000
Reputation: 133879
The elements of a python list
are references to other objects. When you append using self.res.append(num)
, the list is grown by 1 element, and the last element is set to refer to the object pointed to by num
.
Now in the first case, there are 2 references to the same list
object. As self.res[0]
and self.res[1]
refer to the same object, all changes performed through either are also visible through the other.
In the second case, using num[:]
, [:]
operator makes a new list that is copy of the original.
For general algorithm for creating all permutations of a given collection of elements, use the itertools.permutations
:
>>> from itertools import permutations
>>> print(list(permutations([1, 3])))
[(1, 3), (3, 1)]
Upvotes: 4