array[:] 在这个回溯算法中究竟做了什么,或者更确切地说在 Python 中?
What does array[:] exactly do in this backtracking algorithm, or rather in Python?
所以,我正在解决(或者更确切地说,查看解决方案哈哈)关于 Leetcode 的问题,这是一个允许您生成具有唯一整数的数组的所有可能排列的解决方案。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
length = len(nums)
results = []
def backtrack(first_char_index):
if first_char_index == length:
# print(nums == nums[:])
results.append(nums)
for index in range(first_char_index, length):
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(first_char_index + 1)
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(0)
return results
所以,我正在测试解决方案,我意识到这个解决方案只有在 backtrack
函数内的 if
条件下才有效,我使用 results.append(nums[:])
而不是以上results.append(nums)
。
所以一开始我想这可能是因为我们需要生成一个新的副本,所以应该使用nums[:]
,但是后来我在results.append(nums)
之前添加了打印语句,发现所有的打印语句给了我 True
结果。
我记得看到过一些使用 nums[:]
而不是 nums
模式的解决方案,想问问是否有人可以阐明额外的 [:] 到底做了什么?我知道它创建了一个新副本(即不同的对象,但值相同),但由于它具有相同的值,为什么会导致不同的结果?
为了说明这一点,输入 [1, 2, 3]
的结果给出
[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
使用 nums
和
时
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
(正确答案),当使用 nums[:]
.
时
提前致谢!
编辑:出于某种原因,这个问题被认为与其他关于 deep/shallow 复制的问题相同。但是,我想我在这里要问的是,由于 [:]
会产生一个具有 相同值 的新的不同对象,并且 nums
和 nums[:]
是相同的(它打印出来的是更改后的值),它不应该附加一个具有更改后的值的数组,而不是原始的未触及的 nums
数组吗?
nums 和 nums[:] 确实具有相同的值(您使用 == 检查),但它们是不同的对象(您可以使用 'is' 关键字检查)。序列是可变的,因此您可以更改它们包含的值而无需更改对象本身。
[:] 只是创建现有序列的副本。这样你就有了一个不同的对象,其中包含前一个对象的所有值
编辑:
原因是,当您将 nums 附加到结果时,nums 仍然可以更改,即使它在结果中也是如此。因此,每次更改原始 nums 时,结果中的元素都会更改(事实上,结果中所有值都是相同的)。相反,如果您为放入结果中的每个元素创建一个副本,这些元素将全部具有不同的值。
所以,我正在解决(或者更确切地说,查看解决方案哈哈)关于 Leetcode 的问题,这是一个允许您生成具有唯一整数的数组的所有可能排列的解决方案。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
length = len(nums)
results = []
def backtrack(first_char_index):
if first_char_index == length:
# print(nums == nums[:])
results.append(nums)
for index in range(first_char_index, length):
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(first_char_index + 1)
nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
backtrack(0)
return results
所以,我正在测试解决方案,我意识到这个解决方案只有在 backtrack
函数内的 if
条件下才有效,我使用 results.append(nums[:])
而不是以上results.append(nums)
。
所以一开始我想这可能是因为我们需要生成一个新的副本,所以应该使用nums[:]
,但是后来我在results.append(nums)
之前添加了打印语句,发现所有的打印语句给了我 True
结果。
我记得看到过一些使用 nums[:]
而不是 nums
模式的解决方案,想问问是否有人可以阐明额外的 [:] 到底做了什么?我知道它创建了一个新副本(即不同的对象,但值相同),但由于它具有相同的值,为什么会导致不同的结果?
为了说明这一点,输入 [1, 2, 3]
的结果给出
[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
使用 nums
和
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
(正确答案),当使用 nums[:]
.
提前致谢!
编辑:出于某种原因,这个问题被认为与其他关于 deep/shallow 复制的问题相同。但是,我想我在这里要问的是,由于 [:]
会产生一个具有 相同值 的新的不同对象,并且 nums
和 nums[:]
是相同的(它打印出来的是更改后的值),它不应该附加一个具有更改后的值的数组,而不是原始的未触及的 nums
数组吗?
nums 和 nums[:] 确实具有相同的值(您使用 == 检查),但它们是不同的对象(您可以使用 'is' 关键字检查)。序列是可变的,因此您可以更改它们包含的值而无需更改对象本身。 [:] 只是创建现有序列的副本。这样你就有了一个不同的对象,其中包含前一个对象的所有值
编辑: 原因是,当您将 nums 附加到结果时,nums 仍然可以更改,即使它在结果中也是如此。因此,每次更改原始 nums 时,结果中的元素都会更改(事实上,结果中所有值都是相同的)。相反,如果您为放入结果中的每个元素创建一个副本,这些元素将全部具有不同的值。