为什么这个 python 代码会出现副作用?

Why this python code occurs the side-effect?

def to_un(g):
    un = []
    for v in g:
        un.append(v)
    print(g)
    for v in range(len(un)):
        for u in un[v]:
            if v not in un[u]:
                un[u].append(v)
    print(g)
    print(g == un)
    print(g is un)

def main():
    a = [[1], []]
    to_un(a)


if __name__ == "__main__":
    main()

结果:

[[1], []]
[[1], [0]]
True
False

我预计g的值不应该改变但它实际上改变了。 我不知道这段代码发生了什么副作用。

ung 的浅表副本,因此嵌套列表是对两者中相同列表的引用。您还需要复制嵌套列表。

un = [v[:] for v in g]

您可以认为 python 中的列表是通过引用传递的。在这种情况下,g 的元素是列表,这意味着当您执行以下操作时:

un = []
for v in g:
    un.append(v)

您正在将每个列表 v 的引用复制到 un。这意味着如果您更改 un 的元素,您将更改 g 的元素。为避免这种情况,请将上面的行替换为:

import copy
un = copy.deepcopy(g)

这是由于 python 列表中的 'Pass by reference'。您可以通过这样做来获得所需的结果: un[:] = g 代替 un = [] 对于 g 中的 v: un.append(v)