0

I am having issue understanding and solving the following issue with lists, sorting and indexing. Here is the code example:

import random as rdm
a=[]
for i in range(3):
    a.append([i,rdm.randint(-5,5)])
print a
b = sorted(a,key=lambda a:a[1])
print b
c = []
for j in range(len(b)):
    c.append(b[j])
print c
c[0][1] = 0
print a
print b
print c

Notice how changing one value of "C" changed "b" and "a". How can I prevent it from happening? In other words. I do not want the values of "a" changed doesn't matter what happens to "b" or "c"

user1532056
  • 117
  • 1
  • 1
  • 6

2 Answers2

1

In your code, when you write:

c.append(b[j])

You are adding into c a reference to the object b[j].

If you want b and c to be independent of a, you must do a deep copy of the objects.

import copy
b = sorted (copy.deepcopy(a), lambda a : a[1])
ZF007
  • 3,708
  • 8
  • 29
  • 48
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
0

c.append(b[j]) adds into c a reference to the object b[j].

Thereafter, changing c[j] changes b[j]. To avoid this, produce a copy, of b[j], instead: c.append(copy.copy(b[j])) That requires import copy.

Indeed, Python tends to use references instead of copying elements, with certain exceptions (e.g., dict .copy, slicing, sorted(), dict .get() produce shallow copies). Would you write d=b, they would point to the same list (of lists). More: Which commands/methods return a deepcopy / shallowcopy / original?

Would b[j] be a nested list instead of a list (e.g., [[1,2,3],[4,5,6]]), its elements would be pointers (references) to the lists on the next level (to the lists [1,2,3] and [4,5,6]). Then copy.copy(b[j]) would produce a copy (c[j]) of that list of pointers. Changing c[j] would then not affect b but changing c[j][k] before that would affect b[j][k].

Using copy.deepcopy instead of copy.copy always makes the result fully independent, as it recursively copies everything (also the nested lists).

As Storyteller wrote, also b depends on a unless you sort a copy of a instead of a: b = sorted(copy.deepcopy(a), lambda a : a[1]).

Indeed, sorted() produces a shallow copy, so the second level is not copied but pointed to. For non-nested lists, shallow copy is enough for independence.

Convexity
  • 99
  • 3