为什么这个 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的值不应该改变但它实际上改变了。
我不知道这段代码发生了什么副作用。
un
是 g
的浅表副本,因此嵌套列表是对两者中相同列表的引用。您还需要复制嵌套列表。
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)
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的值不应该改变但它实际上改变了。 我不知道这段代码发生了什么副作用。
un
是 g
的浅表副本,因此嵌套列表是对两者中相同列表的引用。您还需要复制嵌套列表。
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)