我目前正在学习Python,遇到分配列表的问题。
在
def nextPermutation(self, nums: List[int]) -> None:
...
我有一行代码可以如下反转列表:
nums = nums[::-1]
但是测试台将其标记为不正确,而
nums[:] = nums[::-1]
还可以。
我怀疑这是因为我正在创建另一个nums
列表对象,并且传入的原始列表没有改变,对吗?
答案 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
是函数的局部变量,因此此更改不会影响作为参数传递的外部变量,如下图所示:
现在考虑这种情况:
def reverse(nums):
nums[:] = nums[::-1]
my_list = [1, 2, 3]
reverse(my_list)
赋值nums[:] = nums[::-1]
等同于在nums
指向的同一地址写入一个新的反向列表 ,因为该分片允许将列表的一部分替换为new内容(尽管在这种情况下,“部分”是整个列表)。
在这种情况下,您没有更改变量nums
,而是更改了它所指向的数据。如下图所示:
请注意,实际上在此答案中,python中的所有变量都是“指针”,但只有列表和字典允许替换“原位”某些内容。对于任何其他类型,您都像在第一种情况中一样“重新分配了指针”,这就是为什么函数不能更改作为参数接收的数据的原因,除了列表情况。