3

Take a look to the following code snippet:

class MyObj(object):
    name = ""

    def __init__(self, name):
        self.name = name

v = [ {} ] * 2

def f(index):
    v[index]['surface'] = MyObj('test')
    v[index]['num'] = 3


if __name__ == '__main__':
    f(0)
    f(1)

    v[0]['num'] = 4
    print v[1]['num']

What I expected to get as output of the last line is a 3; however it prints out 4. So it should mean that the new object is created always at the same reference address.

How can I avoid this behaviour? (i.e. how can I make the above code prints 4?)

Vito Gentile
  • 13,336
  • 9
  • 61
  • 96
  • 1
    Recommended http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly A near dupe – Bhargav Rao May 19 '15 at 21:32

1 Answers1

5

You need to create two dicts:

v = [ {},{} ] 

Or use a loop:

v = [ {} for _ in range(2)] 

You are creating a two references to the same object.

In [2]: a = [{}] * 2

In [3]: id(a[0])
Out[3]: 140209195751176

In [4]: id(a[1])
Out[4]: 140209195751176

In [5]: a[0] is a[1]
Out[5]: True

In [6]: a = [{} for _ in range(2)]  

In [7]: id(a[1])
Out[7]: 140209198435720    

In [8]: id(a[0])
Out[8]: 140209213918728 

In [9]: a[0] is a[1]
Out[9]: False
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321