2

Python beginner here. Reading article about list references, shallow and deep copies, tried out the following:

a = ['a', 'b', 'c']
b = list(a)
a[0] = 'A'

Expected output:

>>>a
['A', 'b', 'c']
>>>b
['A', 'b', 'c']

Actual output:

>>>a
['A', 'b', 'c']
>>>b
['a', 'b', 'c']

However, it is working in the following case:

xs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> ys = list(xs)  # Make a shallow copy

xs[1][0] = 'X'

>>> xs
[[1, 2, 3], ['X', 5, 6], [7, 8, 9]]
>>> ys
[[1, 2, 3], ['X', 5, 6], [7, 8, 9]]

Can someone explain if I am missing something here? Thank you

Python 3.7.4

article link: https://realpython.com/copying-python-objects/

  • What article? You can't distinguish between a deep and shallow copy on a list of immutable objects. – jonrsharpe Aug 03 '19 at 23:13
  • list() function takes any iterable as an argument, so it creates a new list object. Try list(open('text_file', 'r').read()) – Yuri Ginsburg Aug 03 '19 at 23:21
  • I understand that it creates a new list object, but it creates a shallow copy, meaning it is one level deep only. List object is new, but elements of list are still references to the child elements of the original list. I will update my question with the code where it is actually working –  Aug 03 '19 at 23:28
  • 2
    Duplicate of https://stackoverflow.com/a/28684234/9510611 the answer here answers your question – Kevin Glasson Aug 03 '19 at 23:39
  • 1
    @KevinGlasson perfect, exactly what I was looking for. Thanks! –  Aug 03 '19 at 23:42

5 Answers5

1

That's because the list() fuction makes a NEW list, if you do an change to your original list after the assignation, the new list won't change.

You can do that using a variable value, but be careful, for example

var = 'a'
list1 = [var, 'a', 'b']
list2 = list1

print(list1)
print(list2)

output:

['a', 'a', 'b']
['a', 'a', 'b']

You can change the value of var and both lists will change, except if you this:

var = 'a'
list1 = [var, 'a', 'b']
var = 'c'
list2 = list1

print(list1)
print(list2)

output:

['a', 'a', 'b']
['a', 'a', 'b']

Why? Because when you do list1=[var, 'a', 'b'] var has the value of 'a', but when you change its value, this won't affect the list1 because it SAVED the value of var itself, so list2 neither

Axel Anaya
  • 122
  • 9
0

list() creates a new list, meaning changes to the original won't affect the new one.

clubby789
  • 2,543
  • 4
  • 16
  • 32
0

When you say b = list(a), you are making a new list b whose values are the same as those in a. At that point, the elements of each list are equal, but they are not the same object. That is, a change in one of those objects is not reflected in the other. They are independent.

If you say b = a, you are saying that b and a are names that reference the same object.

brentertainer
  • 2,118
  • 1
  • 6
  • 15
0

You can check for yourself what's going on by looking at the 'id' on the object. You can see that b = a creates a new entry in the namespace that simply references the same object as a, but c = a[:] and d = list(a) both create new objects that copy in the contents of a.

a = ['a', 'b', 'c']
id(a)
Out[60]: 4690845768

b = a
id(b)
Out[62]: 4690845768

c = a[:]
id(c)
Out[65]: 4690851848

d = list(a)
id(d)
Out[67]: 4690846728

You've just added the following scenario to the question:

xs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ys = list(xs)

It's true that xs and ys are different objects:

id(ys)
Out[70]: 4691198664
id(xs)
Out[71]: 4690895496

But the nested lists are themselves objects. ys = list(xs) created a new object, but copied the contents - the three nested list objects, across.

id(ys[0])
Out[72]: 4690898696
id(xs[0])
Out[73]: 4690898696
David Buck
  • 3,752
  • 35
  • 31
  • 35
0

What you are expecting is b = a - this will make 'b' reference the SAME list (object) as 'a'.

When you do b = list(a) You create a new list that is independent of 'a'.

Ben Rauzi
  • 564
  • 4
  • 13
  • Thanks! When it is just a reference, it is clear that it will give the result, however I was experimenting with shallow copies and trying to understand the behaviour –  Aug 03 '19 at 23:34