You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python切片与数组原地修改技术咨询:原理、内存复杂度解析

Python切片在列表突变中的机制详解:原地性、内存与执行过程

咱们来逐个拆解你提出的问题,帮你彻底搞懂这个切片操作的细节:

1. 这是原地操作吗?

答案是是的,但要注意区分「变量重新绑定」和「原地修改」的区别:

  • 如果写 nums = nums[-f:] + nums[:-f],这是把变量nums重新绑定到一个新创建的列表对象,原列表会被垃圾回收(如果没有其他引用的话)。
  • 但 nums[:] = nums[-f:] + nums[:-f] 是原地修改原列表:nums[:] 表示对原列表的「完整切片」,赋值时会把右边的元素逐个替换到原列表的对应位置,原列表对象的内存地址不会改变,只是内部的元素被更新了。

2. 内存复杂度是O(1)吗?

不是,整体内存复杂度是O(n),原因在于右边的拼接操作:

  • nums[-f:] + nums[:-f] 会创建一个全新的列表,这个新列表包含原列表的所有n个元素,所以需要占用O(n)的额外内存来存储这个临时列表。
  • 而左边的nums[:]赋值过程本身是原地替换元素,不需要额外的内存空间(除了临时存储拼接后的列表),但整体来看,内存复杂度由右边的拼接操作主导,是O(n),不是O(1)。

3. nums[:] = nums[-f:] + nums[:-f]的完整执行过程

咱们分步骤拆解这个语句的执行顺序:

  1. 计算右侧的两个切片:
    • 先执行nums[-f:]:取原列表的最后f个元素,这会创建一个包含f个元素的临时子列表(对于整数这种不可变类型,切片返回的是元素的引用,不会额外复制元素内容)。
    • 再执行nums[:-f]:取原列表中除了最后f个元素之外的所有元素,同样创建一个包含n-f个元素的临时子列表。
  2. 执行列表加法操作:
    • 把上面两个临时子列表通过+运算符拼接成一个新的完整列表,这个新列表的元素顺序是「后f个元素 + 前n-f个元素」。
  3. 原地替换原列表的元素:
    • 左值nums[:]表示「原列表的所有位置」,Python会把拼接后的新列表中的元素逐个复制到原列表的对应位置,替换掉原有的元素。这个过程不会创建新的列表对象,只是修改原列表内部的元素。

4. 示例分析:nums = [1,2,3,4,5,6,7],f=3

咱们代入数值一步步看:

  • 第一步:nums[-3:]得到[5,6,7],nums[:-3]得到[1,2,3,4]。
  • 第二步:[5,6,7] + [1,2,3,4]拼接成新列表[5,6,7,1,2,3,4],这个新列表会占用额外内存(存储7个整数)。
  • 第三步:nums[:] = 新列表,把原nums的元素从[1,2,3,4,5,6,7]替换成[5,6,7,1,2,3,4],原nums的内存地址不变,只是内容更新了。

关于你问的nums[:]是否占用额外内存:这里的nums[:]作为左值时,并不是创建新列表,而是指向原列表的所有元素位置,所以它本身不会占用额外内存。真正占用额外内存的是右边拼接出来的那个临时新列表。

5. 列表加法操作的具体实现

列表的+运算符本质上是调用了列表的__add__方法,它的实现逻辑大概是这样的:

  • 创建一个新的空列表,预分配足够的空间来容纳左右两个列表的所有元素。
  • 先把左边列表的所有元素依次复制到新列表中。
  • 再把右边列表的所有元素依次复制到新列表的末尾。
  • 返回这个新创建的列表。

所以a + b永远会生成一个新列表,不会修改原列表a或b的内容。

内容的提问来源于stack exchange,提问作者HelloWorld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:06:21