physicalattraction
physicalattraction

Reputation: 6858

Hard copying dicts in a list

When I try the following list creation, I see that each element refers to a different object.

>>> a = [1] * 7
>>> a[0] = 2
>>> a
Out[17]: [2, 1, 1, 1, 1, 1, 1]

However, when I try the following list creation with dictionaries, I see that each element refers to the same object.

a = [{1:10, 2:20}] * 7
a[0][1] = 30
a
Out[20]: 
[{1: 30, 2: 20},
 {1: 30, 2: 20},
 {1: 30, 2: 20},
 {1: 30, 2: 20},
 {1: 30, 2: 20},
 {1: 30, 2: 20},
 {1: 30, 2: 20}]

How can I create this second list as easy as possible, but with the elements copies instead of references?

Upvotes: 1

Views: 39

Answers (2)

Kasravnd
Kasravnd

Reputation: 107297

Actually when you create a list with multiplication python will creating a list with repeated items with same memory address :

>>> a=[1]*7
>>> id(a[0])
40968536
>>> id(a[1])
40968536
>>> a = [{1:10, 2:20}]*7
>>> id(a[0])
140379402804592
>>> id(a[1])
140379402804592

But when you want to change an immutable object like (numbers,tuple,string,...) python will change the reference not the object!

And when you change a mutable object python will change the object itself,so all the entries will change.

So as a more efficient way in python 2 you can use xrange (xrange return a generator instead a list) (in 3 range ) within a list comprehension to create your list :

>>> a = [{1:10, 2:20} for _ in xrange(7)]
>>> a
[{1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]
>>> a[0][1]=0
>>> a
[{1: 0, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]

>>> id(a[0])
140379402734400
>>> id(a[1])
140379402809424

Upvotes: 1

ev-br
ev-br

Reputation: 26050

>>> a = [{1:10, 2:20} for _ in range(7)]
>>> a[0][1] = 30
>>> a
[{1: 30, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}, {1: 10, 2: 20}]

Upvotes: 2

Related Questions