Python更改列表项



我想知道为什么当通过调用函数将值更改为列表时,以下两种情况会有这样的差异(将新值分配给listv.s.分配给list[:](。我想这与按值调用/按引用调用有关。

代码

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之后发生变化。

本页中准确解释了同样的问题Python是通过引用传递还是通过值传递?

正如我们所知,在Python中,"对象引用是按值传递的"。

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

  • nums = nums[-k:]+nums[:-k]导致nums指向一个新对象
  • nums[:] = nums[-k:]+nums[:-k]导致nums所指向的对象发生改变

因此,在方法之外,只有rotate2真正更改ls2的对象。

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

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

相关内容

  • 没有找到相关文章

最新更新