为啥这个参数列表在 Python 中不会改变?

Posted

技术标签:

【中文标题】为啥这个参数列表在 Python 中不会改变?【英文标题】:Why this parameter list doesn't change in Python?为什么这个参数列表在 Python 中不会改变? 【发布时间】:2020-03-11 02:39:04 【问题描述】:

我创建了一个函数 f,它使用一个二维列表作为参数,但是在这个函数之后,列表根本没有改变。 如下代码:

def f(t: [[int]]):
    for eachrow in t:
        eachrow = eachrow[1:]
        eachrow.append(0)

A = [[2, 10, 0], [3, 1, 2], [3, 2, 1]]

f(A)

print(A)  # -> [[2, 10, 0], [3, 1, 2], [3, 2, 1]]

【问题讨论】:

你只是更新循环变量,而不是输入参数 @cricket_007 eachrow 最初是 t 中的一个项目,但切片会覆盖它。我发布了一个关于这个的答案。 顺便说一句,欢迎来到 Stack Overflow ClassicalPi!查看tour。 注意,这不是正确的类型注释:t: [[int]] 应该是t: typing.List[typing.List[int]] 【参考方案1】:

eachrow = eachrow[1:] 中分配给eachrow 会覆盖它。因此,要删除第一个元素,您可以改用del,或row.pop 或slice assignment。

def f(t):
    for row in t:
        del row[0]  # OR row.pop(0) OR row[:] = row[1:]
        row.append(0)

A = [[2, 10, 0], [3, 1, 2], [3, 2, 1]]
f(A)
print(A)  # -> [[10, 0, 0], [1, 2, 0], [2, 1, 0]]

【讨论】:

从技术上讲,并不是切片在进行复制,而是对局部变量进行赋值。如果循环体改为eachrow = 0,您将得到相同的结果。 @wmorrell 你是对的!但是为什么分配给切片有效呢?是不是因为它分配给列表的“内部”而不是名称? @wjandrea 这是切片赋值符号:row[:] = row[1:],它与“分配给切片”不同,也就是说,它不会创建切片(这只是一个新列表)并分配给该新列表,而是简单地修改为原始列表 @wmorrell 要清楚,右侧的eachrow[1:]确实创建了一个切片,即一个全新的list 对象 说一个全新的list 对象有点误导。切片创建一个新的slice,它引用原始的list 项。项目本身不会被复制,这是大多数人在说“new list object”时所期望的。换句话说,a = row[:]a = list(row) 不同。【参考方案2】:

如果您将更改结果打印到eachrow,您会看到您正在更新eachrow 变量,但这不会影响原始t 变量。

def f(t):
    for eachrow in t:
        eachrow = eachrow[1:]
        eachrow.append(0)
        print(eachrow)
>>> f(A)
[10, 0, 0]
[1, 2, 0]
[2, 1, 0]

如果你想影响数组本身,你应该像这样修改数组:

def f(t):
    for row_number in range(len(t)):
        t[row_number] = t[row_number][1:]
        t[row_number].append(0)

【讨论】:

问题不是对t 的迭代,而是切片。我发布了一个关于这个的答案。顺便说一句,列表是可迭代的,而不是迭代器,因为它不会耗尽;而且我认为 Python 没有指针 - Python 名称更像是参考 IIRC。但是索引t 是解决问题的完美方法。 " 该数组元素的迭代器是该列表元素的副本,"绝对不正确。它们不是副本。将任何可变变量放在一个列表中,比如另一个列表:data = [[], []] 然后执行for x in data: x.append(0) 然后打印data,您会看到外部列表中的列表都已被修改。 注意!已在答案中修复。 感谢你们@wjandrea 和 juanpa 看到这个。 @j6m8 哎呀,我错了,不是切片,而是分配。 wmorrel 纠正了我,我更新了我的答案。

以上是关于为啥这个参数列表在 Python 中不会改变?的主要内容,如果未能解决你的问题,请参考以下文章

Python,明明只append了一次,为啥所有子列表都变了啊.jpg

Python中,列表list=变量a,a改变后list为啥不改变呢?

为啥这个while循环在Python中永远不会停止

为啥python的列表切片不会产生索引越界错误? [复制]

深入理解python中的排序sort

python 列表怎样去掉一个元素