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': []}]
kemmotar
  • 199
  • 2
  • 15
  • 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. – jamylak Apr 19 '13 at 13:11

5 Answers5

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.

tomahh
  • 13,441
  • 3
  • 49
  • 70
ibi0tux
  • 2,481
  • 4
  • 28
  • 49
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.

Steve
  • 1,215
  • 6
  • 11
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']}]
ismail
  • 46,010
  • 9
  • 86
  • 95
1

You can try to do:

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

and that should work.

Cheers

XNor
  • 638
  • 3
  • 8
  • 27
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.

thavan
  • 2,409
  • 24
  • 32