python中,数组 nums[:] 和nums有何区别?

leetcode中有一道题。题目为:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

错误代码:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        for i in nums:
            print('----', i)
            if i == val:
                nums.remove(val)
                print(len(nums),nums)
        print(nums)
        return len(nums)

正确代码:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        for i in nums[:]:
            print('----', i)
            if i == val:
                nums.remove(val)
                print(len(nums),nums)
        print(nums)
        return len(nums)

从以上可以看到,他们之间差了一个[:]

但是单独执行:

    for i in nums[:]:
        print('i',i)
    for ii in nums:
        print('ii',ii)

输出结果一抹抹一样样,这是为什么呢?

在 Python 中,nums 是一个列表对象。nums[:] 表示对这个列表进行切片操作,切片操作的结果是返回一个新的列表对象,其中包含了原列表中的所有元素。

虽然 nums 和 nums[:] 看起来很相似,但它们之间有一个重要的区别。当你将 nums 分配给某个变量时,该变量实际上仅仅是指向了原始列表对象的引用,因此对该变量的任何更改都会反映在原始列表对象上。例如:

nums = [1, 2, 3]
new_nums = nums

new_nums[0] = 0

print(nums)  # 输出 [0, 2, 3]

然而,如果你使用 nums[:] 来创建一个新的列表对象,则对新列表对象的任何更改都不会影响原始列表对象。例如:

nums = [1, 2, 3]
new_nums = nums[:]

new_nums[0] = 0

print(nums)  # 输出 [1, 2, 3]

在这个例子中,我们使用 nums[:] 创建了一个新的列表对象 new_nums,并将其赋值给变量 new_nums。然后我们修改了 new_nums 中的第一个元素,但是原始列表 nums 没有被修改。

因此,nums 和 nums[:] 的区别在于,前者是一个指向原始列表对象的引用,而后者是一个新的、独立的列表对象。

由此可以解释上列leetcode题解了。实际上切片是生成了一个新的拷贝。而不是引用。

猜你喜欢

转载自blog.csdn.net/wywinstonwy/article/details/131476848