nums [:] = nums [::-1]和nums = nums [::-1]之间的差异

时间:2019-07-22 19:42:24

标签: python python-3.x

我目前正在学习Python,遇到分配列表的问题。

def nextPermutation(self, nums: List[int]) -> None:
    ...

我有一行代码可以如下反转列表:

nums = nums[::-1]

但是测试台将其标记为不正确,而

nums[:] = nums[::-1]

还可以。

我怀疑这是因为我正在创建另一个nums列表对象,并且传入的原始列表没有改变,对吗?

2 个答案:

答案 0 :(得分:5)

您的假设完全正确。

我们可以通过使用内置函数id来获取内存中对象的地址来进行验证

尝试运行:

def func(nums):
    print(id(nums),"before change")
    nums[:] = nums[::-1]
    print(id(nums), "after [:]")
    nums = nums[::-1]
    print(id(nums), "after regular assign")

a = [1,2,3]
print(id(a),"original")
func(a)

输出(数字可能会有所不同)

55313512 original
55313512 before change
55313512 after [:]
55297688 after regular assign

如您所见,最后一个id返回一个不同的值,而其余(从函数内部和外部)返回相同的值。

答案 1 :(得分:4)

如果您了解C和指针,则可以将nums用作指向列表的指针。

考虑这种情况:

def reverse(nums):
    nums = nums[::-1]

my_list = [1, 2, 3]
reverse(my_list)

分配nums = nums[::-1]等效于在内存中创建一个新列表(元素反转),并更改指针nums指向该新列表。但是由于您更改的变量nums是函数的局部变量,因此此更改不会影响作为参数传递的外部变量,如下图所示:

bad

现在考虑这种情况:

def reverse(nums):
   nums[:] = nums[::-1]

my_list = [1, 2, 3]
reverse(my_list)

赋值nums[:] = nums[::-1]等同于在nums指向的同一地址写入一个新的反向列表 ,因为该分片允许将列表的一部分替换为new内容(尽管在这种情况下,“部分”是整个列表)。

在这种情况下,您没有更改变量nums,而是更改了它所指向的数据。如下图所示:

right

请注意,实际上在此答案中,python中的所有变量都是“指针”,但只有列表和字典允许替换“原位”某些内容。对于任何其他类型,您都像在第一种情况中一样“重新分配了指针”,这就是为什么函数不能更改作为参数接收的数据的原因,除了列表情况。