python中的list.append(a [:])和list.append(a)有什么区别?

时间:2020-04-30 15:46:33

标签: python list

这与leetcode问题39有关。 我从results.append(solution)开始,它没有正确地添加到列表中,并在解决方案中发现results.append(solution[:])可以正常工作。这两种语法有什么区别?

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

3 个答案:

答案 0 :(得分:3)

a[:]将创建一个新列表。 c.append(b)将列表b附加到c

以下代码将有助于更好地理解这一点-


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

答案 1 :(得分:1)

从对象id中可以看到,进行切片会创建一个新列表

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

直接分配列表是指同一对象

>>> b = a
>>> id(b)
2711680383816

答案 2 :(得分:0)

a是一个列表,a[:]是一个复制了所有元素的新列表。

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

我们还有另一个列表b = ["a", "b"]append将您提供的所有内容添加到列表的末尾。如果您追加另一个列表,则对该列表的 reference 会被添加,并可能导致意外的行为:

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

您可以看到,在追加a之后,如果您在a中更改了元素,那么它在b中也会更改。这是因为b仅对a具有引用。为防止这种情况,您可以改为执行b.append(a[:])。这将复制 a中的值,因此当您随后更改a中的值时,b中的值将保持复制时的状态:

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

因此,在您的问题中,使用solution[:]确保results的下一次迭代发生solution.append时添加到for的内容不会改变循环。