5

Can anyone explain why this happened with list and how to clean list after appending to another list?

>>> t = {} >>> t["m"] = [] >>> t {'m': []} >>> t["m"].append('qweasdasd aweter') >>> t["m"].append('asdasdaf ghghdhj') >>> t {'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']} >>> r = [] >>> r.append(t) >>> r [{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}] >>> t["m"] = [] >>> r [{'m': []}] 
1
  • 1
    You are calling this behaviour strange, assuming that python will implicitly copy the whole dictionary when you append to r, In almost every case Python doesn't do anything unless you've explicitly told it to. Commented Apr 19, 2013 at 13:11

5 Answers 5

10

That's a normal behaviour. Python uses references to store elements. When you do r.append(t) python will store t in r. If you modify t later, t in r will be also modified because it's the same object.

If you want to make t independant from the value stored in r you have to copy it. Look at the copy module.

Sign up to request clarification or add additional context in comments.

Comments

2

When you call r.append(t) you are saying "Store a reference to the value stored in t at the end of the list r". The dictionary t references is not copied, so when you modify t you modify the data referenced by r.

This behaviour can be seen more clearly here:

>>> x = [] >>> y = x >>> x.append(1) >>> y [1] 

This sets y to the value referenced by x so when x changes it appears that y changes as well.

Comments

1

Dictionaries are mutable in Python, take a copy instead

>>> import copy >>> r.append(copy.copy(t)) >>> t {'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']} >>> r [{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}] >>> t["m"]=None >>> r [{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}] 

Comments

1

You can try to do:

import copy r.append(copy.deepcopy(t)) 

and that should work.

Cheers

Comments

1

This is normal. When you assign a object to a variable, python won't copy that object to your variable. It will simply assign the reference of original object to your new object.

In [1]: a = [1,2] In [2]: b = a In [3]: a.remove(1) In [4]: b Out[4]: [2] 

Here b will only hold the reference of original list a. If you want to override this behavior, you can use the copy module.

In [7]: import copy In [8]: a = [1,2] In [9]: b = copy.deepcopy(a) In [10]: a.remove(1) In [11]: b Out[11]: [1, 2] 

deepcopy duplicates everything including individual elements.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.