1
listOne = [1, 2, 3]
listTwo = listOne

print(listOne) #[1, 2, 3]

listTwo.append(4)

print(listOne) #[1, 2, 3, 4]
print(listtwo) #[1, 2, 3, 4]

Here my doubt is that we are assigning listOne to list two. That is listTwo is pointing to listOne. So when we append the value to listTwo why is it reflecting in listOne as well? I am new to python. Please help me out.

SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87
  • 1
    change `listTwo = listOne` to `listTwo = listOne[:]` – eyllanesc Apr 01 '18 at 05:00
  • it is because it is pointing to same list in memory, if you want it to be a new list then just copy the listOne – johnII Apr 01 '18 at 05:00
  • Actually .append() is appending in list one which is equal to list 2 . so they will remaim the same – toheedNiaz Apr 01 '18 at 05:02
  • 2
    [Facts and myths about Python names and values](https://nedbatchelder.com/text/names.html) – wwii Apr 01 '18 at 05:03
  • `listOne` and `listTwo` refer to the same list. That is what `listOne = listTwo` means in Python, that says "the name `listOne` now refers to the same object as the name `listTwo`. No new objects are created. – juanpa.arrivillaga Apr 01 '18 at 05:28

3 Answers3

4

listOne is pointing to the contents of the list. Then listTwo = listOne will just create another pointer (listTwo) to that same list. So when you do anything to either pointer, e.g. listTwo.append(4), you will affect the list that both listOne and listTwo are pointing to.

To make a copy of the list, use listTwo = listOne[:], which will create an entirely new list which listTwo points to.

Ollie
  • 1,641
  • 1
  • 13
  • 31
4

In Python everything is an object, and what that means is everything gets it own memory.

When you initialized listOne = [1, 2, 3], it was given a memory address.

You then used the assignment operator = to assign the memory location of listOne to listTwo.

So if we take your example:

listOne = [1, 2, 3]
listTwo = listOne

We can do:

listOne is listTwo
#Output: True

Somebody mentioned you can use the slice operator : but that gives you a Shallow Copy. If you're not familiar with the difference between Shallow and Deep Copy, read these docs. Basically, a Shallow Copy is a new outer container object (the [ ] and the internal elements are references to the same memory locations. A Deep Copy is also a new outer container but gets brand new copies of the objects inside (i.e. identical copies of the objects but at new memory locations).

I leave you with this example of a Shallow Copy with non-primative types (i.e. not int's like yours):

>>> class Sample:
        def __init__(self, num):
            self.num = num
            self.id = id(self)

>>> s1 = Sample(1)
>>> s2 = Sample(2)

>>> listOne = [s1, s2]
>>> listOne[0].num
1
>>> listOne[0].id
88131696
>>> listOne[1].num
2
>>> listOne[1].id
92813904

# so far we know that listOne contains these unique objects

>>> listTwo = listOne
>>> listTwo[0].num
1
>>> listTwo[0].id
88131696
>>> listTwo[1].num
2
>>> listTwo[1].id
92813904

# well shoot, the two lists have the same objects!
# another way to do show that is to simply print the lists

>>> listOne
[<__main__.Sample object at 0x0540C870>, <__main__.Sample object at 0x05883A50>]
>>> listTwo
[<__main__.Sample object at 0x0540C870>, <__main__.Sample object at 0x05883A50>]

# those odd number sequences are hexadecimal and represent the memory location
# to prove the point further, you can use the built in hex() with id()

>>> hex(listOne[0].id) # id is 88131696 from above
'0x540c870'
pstatix
  • 3,611
  • 4
  • 18
  • 40
  • Nitpick: "it was given a memory address on the stack." I don't think that's technically correct for CPython. From the [docs](https://docs.python.org/3.6/c-api/memory.html): "*Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the Python memory manager. The Python memory manager has different components which deal with various dynamic storage management aspects, like sharing, segmentation, preallocation or caching.*" – juanpa.arrivillaga Apr 01 '18 at 05:38
  • @juanpa.arrivillaga Fair point, updated – pstatix Apr 02 '18 at 13:41
2

When you copying a list to another list using = sign, both the list refer to the same list object in the memory. So modifying one list, other automatically changes as they both refer to same object. To copy a list use slice operator or copy module.

>>>list1=[1,2,3]
>>>list2=list1[:]
>>>list2.append(4)
>>>list1
[1,2,3]
>>>list2
[1,2,3,4]
>>>import copy
>>>list3=copy.deepcopy(list1)
>>> list3.append(4)
>>>list1
[1,2,3]
>>>list3
[1,2,3,4]
Ranjeet
  • 360
  • 2
  • 4
  • 13