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

Python列表传参疑问:为何print(v,m,n)输出全为[3,6,9]?

Python列表操作的输出疑惑解答

题目选项

  • a) [1, 2, 3], [2, 4, 6], [3, 6, 9]
  • b) [3, 6, 9], [3, 6, 9], [3, 6, 9]
  • c) [1, 2, 3], [1, 2, 3], [3, 6, 9]
  • d) [1, 2, 3], [1, 2, 3], [2, 4, 6]
  • e) [3, 6, 9], [1, 2, 3], [3, 6, 9]

问题详情

我是Python初学者,运行以下代码后,实际输出和预期完全不符,搞不懂为什么:

运行代码

def f1(v):
    for elem in v:
        elem *= 2
    return v

def f2(m):
    for i in range(len(m)):
        m[i] *= 3
    return m

v = [1,2,3]
m = f1(v)
n = f2(v)

print(v, m, n)

预期输出

[1, 2, 3]
[1, 2, 3]
[3, 6, 9]

实际输出

[3, 6, 9]
[3, 6, 9]
[3, 6, 9]

我原本以为调用f1(v)后m应该是[1,2,3],调试时执行n = f2(v)前也确实看到m是这个值,但最终三个变量输出全是[3,6,9],正确答案是选项b,求解释原因。

核心原因:列表是可变对象,传递的是引用

Python里列表属于可变对象,当你把列表传给函数时,传的不是列表的副本,而是它在内存中的引用。也就是说,函数内部对这个列表的修改,会直接改动原列表本身。

逐行拆解执行过程

  1. 初始化列表:v = [1,2,3],内存中生成一个列表对象,v指向这个对象。
  2. 调用f1(v):
    • 函数里的参数v和外部的v是同一个列表的引用。
    • 循环里的elem *= 2:elem是列表元素的临时变量,因为整数是不可变对象,修改elem只是给这个临时变量重新赋值了一个新整数,根本没改动原列表里的元素。所以f1返回的还是原列表的引用,m和v指向同一个列表,此时两者都是[1,2,3]。
  3. 调用f2(v):
    • 函数接收的参数同样指向原列表对象。
    • 循环里的m[i] *=3是直接通过索引修改列表元素,这会直接改变原列表的内容,原列表从[1,2,3]变成[3,6,9]。
    • f2返回的还是原列表的引用,所以n也指向这个被修改后的列表。
  4. 打印输出:此时v、m、n都指向内存中同一个列表对象,这个对象已经被f2改成了[3,6,9],所以三者输出完全一样。

解释你的调试现象

你调试时在执行n = f2(v)前看到m是[1,2,3],那是因为f2还没执行,原列表还没被修改。但执行f2(v)后,原列表被改变,而m和v指向同一个对象,所以m的值也会同步变成[3,6,9]——你看到的调试值是修改前的状态,修改后所有指向该对象的变量都会跟着变。

如何得到预期输出

如果想让m、n是独立的列表,需要在函数内部创建列表副本,比如:

  • 修改f1:把返回语句改成return v.copy()(或者return list(v)、return v[:])
  • 修改f2:先复制列表再修改,示例代码:
def f2(m):
    new_m = m.copy()
    for i in range(len(new_m)):
        new_m[i] *= 3
    return new_m

这样每个函数返回的都是新的列表对象,不会影响原列表,就能得到你预期的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:50:20