Разница между arr.append(curr)
и arr.append(curr[:])
заключается в том, что первый копирует адрес списка curr
в arr
, а второй копирует значения curr
в arr
.
Давайте посмотрим на разницу на примерах.
Первый сценарий:
curr = [5, 10, 15, 20]
arr = []
arr.append(curr)
print("Before update")
print("Curr: {}\nArr: {}".format(curr, arr))
curr[1] = 7
print("After update")
print("Curr: {}\nArr: {}".format(curr, arr))
Вывод:
Before update
Curr: [5, 10, 15, 20]
Arr: [[5, 10, 15, 20]]
After update
Curr: [5, 7, 15, 20]
Arr: [[5, 7, 15, 20]]
Второй сценарий:
curr = [5, 10, 15, 20]
arr = []
print("Before update")
arr.append(curr[:])
print("Curr: {}\nArr: {}".format(curr, arr))
curr[1] = 7
print("After update")
print("Curr: {}\nArr: {}".format(curr, arr))
Вывод :
Before update
Curr: [5, 10, 15, 20]
Arr: [[5, 10, 15, 20]]
After update
Curr: [5, 7, 15, 20]
Arr: [[5, 10, 15, 20]]
Как вы можете видеть в первом сценарии, как curr
, так и arr
обновляются при изменении одного значения индекса в списке curr
. Поскольку добавление curr
к arr
содержит тот же адрес памяти.
Во втором сценарии только curr
обновляется при изменении одного значения индекса в списке curr
. Поскольку добавление [:]
к arr
копирует содержимое из списка curr
в список arr
.
Согласно сказанному выше (теория), причина, по которой вы получаете [[], [], [], [], [], [], [], []]
при запуске изменение кода curr
на curr[:]
связано с тем, что в последней строке curr.pop()
в функции backtrack вы удаляете последние элементы один за другим, поэтому вы удаляете элементы из списка, который все время находится в одной и той же пространственной памяти, а не из ее значений из списка копий.