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?)

1

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

6 Comments

@AmiTavory Note that Whenever you see [ {} ] * 2 or [ [] * 0] It is THE culprit
@Bhargav Rao Unfortunately, my brain's lexer is slower than some other peoples' bytecode compiler. :-)
@AmiTavory You better compile this answer into a pyc file and store it in your persistent storage. :P
@AmiTavory, I learned everything I know from the master Bhargav Rao ;)
@BhargavRao, I dunno,I have been told I have an honset face ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.