Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: why does my list change when I'm not actually changing it?

Tags:

python

alias

list

Newbie with a question, so please be gentle:

list = [1, 2, 3, 4, 5]
list2 = list

def fxn(list,list2):
    for number in list:
        print(number)
        print(list)
        list2.remove(number)
        print("after remove list is  ", list, " and list 2 is  ", list2)
    return list, list2

list, list2 = fxn(list, list2)
print("after fxn list is  ", list)
print("after fxn list2 is  ", list2)

This results in:

1
[1, 2, 3, 4, 5]
after remove list is   [2, 3, 4, 5]  and list 2 is   [2, 3, 4, 5]
3
[2, 3, 4, 5]
after remove list is   [2, 4, 5]  and list 2 is   [2, 4, 5]
5
[2, 4, 5]
after remove list is   [2, 4]  and list 2 is   [2, 4]
after fxn list is   [2, 4]
after fxn list2 is   [2, 4]

I don't understand why list is changing when I am only doing list2.remove(), not list.remove(). I'm not even sure what search terms to use to figure it out.

like image 906
user1604149 Avatar asked Aug 16 '12 19:08

user1604149


2 Answers

The reason this is happening can be found here:

mlist = [1,2,3,4,5]
mlist2 = mlist

the second statement "points" mlist2 to mlist (i.e., they both refer to the same list object) and any changes you make to one is reflected in the other.

To make a copy instead try this (using a slice operation):

mlist = [1,2,3,4,5]
mlist2 = mlist[:]

In case you are curious about slice notation, this SO question Python Lists(Slice method) will give you more background.

Finally, it is not a good idea to use list as an identifier as Python already uses this identifier for its own data structure (which is the reason I added the "m" in front of the variable names)

like image 105
Levon Avatar answered Sep 30 '22 01:09

Levon


That's because both list and list2 are referring to the same list after you did the assignment list2=list.

Try this to see if they are referring to the same objects or different:

id(list)
id(list2)

An example:

>>> list = [1, 2, 3, 4, 5]
>>> list2 = list
>>> id(list)
140496700844944
>>> id(list2)
140496700844944
>>> list.remove(3)
>>> list
[1, 2, 4, 5]
>>> list2
[1, 2, 4, 5]

If you really want to create a duplicate copy of list such that list2 doesn't refer to the original list but a copy of the list, use the slice operator:

list2 = list[:]

An example:

>>> list
[1, 2, 4, 5]
>>> list2
[1, 2, 4, 5]
>>> list = [1, 2, 3, 4, 5]
>>> list2 = list[:]
>>> id(list)
140496701034792
>>> id(list2)
140496701034864
>>> list.remove(3)
>>> list
[1, 2, 4, 5]
>>> list2
[1, 2, 3, 4, 5]

Also, don't use list as a variable name, because originally, list refers to the type list, but by defining your own list variable, you are hiding the original list that refers to the type list. Example:

>>> list
<type 'list'>
>>> type(list)
<type 'type'>
>>> list = [1, 2, 3, 4, 5]
>>> list
[1, 2, 3, 4, 5]
>>> type(list)
<type 'list'>
like image 31
Susam Pal Avatar answered Sep 30 '22 01:09

Susam Pal