В чем разница между list.append (a [:]) и list.append (a) в python? - PullRequest
0 голосов
/ 30 апреля 2020

Это связано с проблемой кода 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 ]

3 голосов
/ 30 апреля 2020

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 голос
/ 30 апреля 2020

Как видно из id объектов, создание среза создает новый список

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

, тогда как назначение списка напрямую относится к тому же объекту

>>> b = a
>>> id(b)
2711680383816
0 голосов
/ 30 апреля 2020

a - это список, а a[:] - это новый список со всеми скопированными элементами.

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

Давайте создадим другой список b = ["a", "b"]. append добавляет все, что вы даете, в конец списка. Если вы добавите другой список, ссылка к этому списку будет добавлена ​​и может привести к непредвиденному поведению:

>>> 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 l oop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...