0
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()

result:

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

I expected that the value of g should not changed but it actually changed. I don't know what side-effect was occurred in this code.

John Gordon
  • 29,573
  • 7
  • 33
  • 58

3 Answers3

1

un is a shallow copy of g, so the nested lists are references to the same lists in both. You need to copy the nested lists as well.

un = [v[:] for v in g]
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

You can think of lists in python being passed by reference. In this case, the elements of g are lists, which means when you do:

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

You're copy the references of each list v, to un. This means if you change the elements of un, you'll change the elements of g. To avoid this, replace the above lines with:

import copy
un = copy.deepcopy(g)
Jay Mody
  • 3,727
  • 1
  • 11
  • 27
0

This is due to 'Pass by reference' in list in python. You can achieve the results you need by doing just this: un[:] = g Instead of un = [] for v in g: un.append(v)

Pratik Joshi
  • 389
  • 4
  • 13
  • This is due to 'Pass by reference' in list in python. You can achieve the results you need by doing just this: un[:] = g Instead of un = [] for v in g: un.append(v) – Pratik Joshi May 23 '20 at 13:26