Python 更改列表项

Python change list item

我想知道为什么通过调用函数将值更改为列表时,在以下两种情况下会有这样的差异(将新值分配给list v.s. 到 list[:])。我想这与 call-by-value/call-by-reference.

有关

代码

def rotate1(nums, k) -> None:   
  nums = nums[-k:]+nums[:-k]
  print(f"In rotate1: {nums}")
  
def rotate2(nums, k) -> None:   
  nums[:] = nums[-k:]+nums[:-k]
  print(f"In rotate2: {nums}")  

ls1 = [1,2,3,4]
rotate1(ls1, 2)
print(f"Outside rotate1: {ls1}\n")

ls2 = [1,2,3,4]
rotate2(ls2, 2)
print(f"Outside rotate2: {ls2}\n")

输出

In rotate1: [3, 4, 1, 2]
Outside rotate1: [1, 2, 3, 4]

In rotate2: [3, 4, 1, 2]
Outside rotate2: [3, 4, 1, 2]

调用rotate1后ls1值不变; 而 ls2 值在调用 rotate2 后发生变化。

在您的函数 rotate1 中,您正在分配一个新变量 nums 来替换参数中的变量 nums。这不会影响函数外部的列表,因为您正在替换指向内存中分配值的位置的变量,而不是更改内存中的值。本质上,您的新列表 [3, 4, 1, 2] 存储在内存中的新地址中。现在你的原始列表 ls1 和新列表 nums 分配在内存中的不同地址。

在您的函数 rotate2 中,您正在更改存储在内存中的值,而不是更改指针。当您使用 nums[:] 时,变量 nums 保持不变,变量 nums 指向的内存中的值发生了什么变化。这就是为什么你外面的列表也会更新。

同样的问题在本页中得到了准确的解释Is Python pass-by-reference or pass-by-value?

As we know, in Python, “Object references are passed by value”.

在两个旋转方法中,nums 创建一个新变量指向对象 [1,2,3,4]。区别是:

  • nums = nums[-k:]+nums[:-k] 导致 nums 指向新对象。
  • nums[:] = nums[-k:]+nums[:-k] 导致 nums 指向的对象改变。

所以,在方法之外,只有 rotate2 真正改变了 ls2 的对象。