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

Python函数中NumPy数组与列表是否会被修改?如何避免原值改动?

传入Python函数的列表与NumPy数组是否会被内部操作修改

Python的参数传递是对象引用传递,不存在其他语言里非黑即白的值传递/引用传递划分,传入的列表和NumPy数组会不会被修改,完全取决于函数内部对传入对象执行的操作,两类对象的具体表现如下:

  • 列表的修改规则
    列表是典型的可变对象,如果函数内部对传入的列表执行原地修改操作,外部的原始列表会被直接改动,常见的原地操作包括:调用append()/pop()/extend()/sort()这类原地方法、按索引/切片给元素赋值、用+=做列表拼接。
    示例代码:
    def change_list(input_list):
        input_list.append(4)
        input_list[0] = 999
    
    origin = [1,2,3]
    change_list(origin)
    print(origin)  # 输出 [999, 2, 3, 4],原始列表已被修改
    
    如果函数内部只是把传入的参数变量重新指向新的列表对象,或者执行sorted()、列表+运算这类返回新对象的非原地操作,就不会影响外部的原始列表。
  • NumPy数组的修改规则
    NumPy数组同样是可变对象,且其设计偏向高性能,大量操作默认是原地执行,只要函数内对传入的数组做原地修改(按索引/切片赋值、调用sort()/fill()这类原地方法、用+=/*=这类原地运算符),都会直接改动原始数组。
    要特别注意:NumPy数组的切片默认是原数组的视图,不是独立拷贝,哪怕函数里只修改了原数组的切片,也会联动修改原始数组——这一点和Python原生列表不同,原生列表的切片是浅拷贝,修改切片不会影响原列表。
    示例代码:
    import numpy as np
    def change_arr(arr):
        arr[0] = 100
        arr *= 2
    
    origin_arr = np.array([1,2,3])
    change_arr(origin_arr)
    print(origin_arr)  # 输出 [200   4   6],原始数组已被修改
    
    和列表一样,如果函数内部只是把参数变量重新赋值为新的数组对象,不会对外部原始数组产生任何影响。
避免原始值被意外修改的可行措施
  • 传入前主动生成独立副本
    这是最直接、最不容易出问题的方案:
    • 对普通列表:如果元素都是数字、字符串这类不可变类型,用origin.copy()、list(origin)或者切片origin[:]生成浅拷贝即可;如果列表嵌套了列表、字典这类可变元素,需要用copy.deepcopy(origin)生成递归深拷贝,才能完全切断和原对象的关联。
    • 对NumPy数组:直接调用origin_arr.copy()即可生成内存完全独立的深拷贝,把这个副本传入函数,后续任何操作都不会影响原始数组。
  • 函数内部做防御性拷贝
    如果你是函数的开发者,且函数逻辑本身不应该改动用户传入的原始数据,可以在函数入口处第一时间对传入参数做拷贝,后续所有逻辑都在副本上执行。比如处理数值数据的函数可以在开头写arr = np.array(arr, copy=True),不管用户传入的是列表还是NumPy数组,都会自动生成独立副本,从根源上避免误改外部数据。
  • 刻意规避容易触发原地修改的写法
    • 操作列表时,优先用返回新对象的非原地方法:比如排序用sorted(input_list)代替input_list.sort(),拼接元素用new_list = input_list + [elem]代替append()。
    • 操作NumPy数组时,对传入的原始数组避免使用+=/-=这类原地运算符,换成arr = arr * 2这类生成新数组的写法;如果需要操作数组切片,先给切片做.copy()再修改,避免视图联动改到原数组。
  • 调试阶段用只读锁做校验
    排查误改问题时,可以在传入NumPy数组前把它设为只读:origin_arr.flags.writeable = False,之后任何尝试修改该数组的操作都会直接抛出ValueError,可以快速定位到误改的代码位置。

注意:浅拷贝只会复制最外层的容器对象,容器内部存储的可变元素依然和原对象共享引用,只要存在嵌套可变结构的场景,要完全隔离原始值必须使用深拷贝。

内容的提问来源于stack exchange,提问作者Prathvik G S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:54:29