使用[:]有什么意义?

时间:2019-07-15 00:45:52

标签: python python-3.x list append heaps-algorithm

我今天正在研究某人使用Python3的堆算法回溯的解决方案。解决方案如下:

def permute(self, nums):
    def backtrack(start, end):
        if start == end:
            ans.append(nums[:])
        for i in range(start, end):
            nums[start], nums[i] = nums[i], nums[start]
            backtrack(start+1, end)
            nums[start], nums[i] = nums[i], nums[start]

    ans = []
    backtrack(0, len(nums))
    return ans

现在我正在看ans.append(nums[:])行,写nums[:]的意义是什么?无法正确编写nums函数吗?

2 个答案:

答案 0 :(得分:7)

请考虑以下内容

>>> a = [1,2,3]
>>> b = [a]
>>> b[0].append(4)
>>> a
[1, 2, 3, 4]

如您所见,修改b[0]会修改a,因为您已将对象a存储在b中,而不仅仅是a的值。因此,使用[:]可以复制列表。

>>> a = [1,2,3]
>>> b = [a[:]]
>>> b[0].append(4)
>>> a
[1, 2, 3]

所以重点是传递值,而不是对象本身。

答案 1 :(得分:2)

不,这是不一样的,因为在for循环中您正在突变nums

 nums[start], nums[i] = nums[i], nums[start]

如果在答案中附加对nums的引用,而不是独立复制,则将对所有组装者的子元素进行突变,并最终列出所有反映最终值的相同置换。您可以尝试一下并查看结果:

def permute(nums):
    def backtrack(start, end):
        if start == end:
            ans.append(nums)
        for i in range(start, end):
            # changing sums which will be reflected in all
            # references to nums in the ans array
            nums[start], nums[i] = nums[i], nums[start]
            backtrack(start+1, end)
            nums[start], nums[i] = nums[i], nums[start]

    ans = []
    backtrack(0, len(nums))
    return ans

permute([1, 2, 3])

都一样:

[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

您可以确认它们都指向内存中的同一对象:

l = permute([1, 2, 3])
[id(el) for el in l]

> [140539119291912, # all the same reference
   140539119291912,
   140539119291912,
   140539119291912,
   140539119291912,
   140539119291912]

通过使用ans.append(nums[:]),您可以进行复制,因此nums的进一步突变不会影响您已经拥有的组合。