简体   繁体   中英

What's the difference between list.append(a[:]) and list.append(a) in python?

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

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]
>>>

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM