0

This is related to leetcode problem #39. I started with results.append(solution), which does not append properly to the list, and found in the solution that results.append(solution[:]) works. What's the difference between these two syntax?

class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
    results=[]
    def backtracking(candidates,target,start,solution,results):
        #print(start,target,solution,results)
        if target<0:
            return
        if target==0:
            results.append(solution[:])
            return

        for i in range(start,len(candidates)):
            solution.append(candidates[i])
            backtracking(candidates,target-candidates[i],i,solution,results)
            solution.pop()


    backtracking(candidates,target,0,[],results)
    return results
mahoriR
  • 4,377
  • 3
  • 18
  • 27
Arky Yang
  • 3
  • 2

3 Answers3

3

a[:] will create a new list. c.append(b) appends the list b to c.

Following code will help understand this better -


>>> a=[1,2,3]
>>> b=[4,5]
>>> c=[1,2,3]
>>> a.append(b) #append b
>>> c.append(b[:]) #create new list and append
>>> a
[1, 2, 3, [4, 5]]
>>> c
[1, 2, 3, [4, 5]]
>>> b
[4, 5]
>>> a[3][0]=99 #modify a
>>> a
[1, 2, 3, [99, 5]] #a modified
>>> b
[99, 5] #so does b
>>> c
[1, 2, 3, [4, 5]] #modify c
>>> c[3][1]=99
>>> c #c modified
[1, 2, 3, [4, 99]]
>>> b #original b did not get modified
[99, 5]
>>>

mahoriR
  • 4,377
  • 3
  • 18
  • 27
1

As you can see from the id of the objects, making a slice creates a new list

>>> a = [1, 2, 3]
>>> id(a)
2711680383816
>>> id(a[:])
2711683338696

whereas assigning the list directly refers to the same object

>>> b = a
>>> id(b)
2711680383816
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
0

a is a list and a[:] is a new list with all elements copied.

>>> a = [1, 2, 3]
>>> a == a[:]
True
>>> a is a[:]
False

Let's have another list b = ["a", "b"]. append adds whatever you give it to the end of a list. If you append another list, the reference to that list gets added and might lead to un expected behaviours:

>>> b.append(a)
>>> b
["a", "b", [1, 2, 3]]
>>> a[0] = "c"
>>> b
["a", "b", ["c", 2, 3]]
>>> b[2][1] = 42
>>> a
["c", 42, 3]
>>> a is b[2]
True

You can see, that after appending a, if you change an element in a, it also changes in b. This is because b only has a reference to a. To prevent that, you can instead do b.append(a[:]). This will copy the values in a, so when you then change values in a, values in b stay what they were when you copied them:

>>> b.append(a)
>>> b
["a", "b", [1, 2, 3]]
>>> a[0] = "c"
>>> b
["a", "b", [1, 2, 3]]
>>> b[2][1] = 42
>>> a
["c", 2, 3]
>>> a is b[2]
False

So in your question, using solution[:] makes sure that whatever has been added to the results doesn't change when solution.append happens on the next iteration of the for loop.

Faboor
  • 1,365
  • 2
  • 10
  • 23