Copmlex structures....

Jeff Shannon jeff at ccvcorp.com
Fri Mar 22 19:17:19 EST 2002


"Dmitry S. Makovey" wrote:

> 01. >>> f={}
> 02. >>> f['name']='dimon'
> 03. >>> f['age']=20
> 04. >>> a=[]
> 05. >>> a.append(f)
> 06. >>> print a
> 07. [{'age': 20, 'name': 'dimon'}]
> 08. >>> f['age']=22
> 09. >>> print a
> 10. [{'age': 22, 'name': 'dimon'}]
>
> I don't like result in the last like I've expected to have [{'age': 20,
> 'name': 'dimon'}], how could i do this?
>
> I know that it must be as simple as using something like b[:], but what?

When you append f to your list, you end up having *two* references to the same
dictionary -- one of those references is f, and the other is a[0] -- but they
both point to the *same* dictionary, meaning that changing it in one place
affects it regardless of which way you access it.  It's like you've given it a
nickname.

What you need to do, is add a *copy* of the dictionary to your list.

import copy
a.append( copy.copy(f) )

Now, the dictionary referred to by a[0] is independent of the dictionary
pointed to by f, and you can change f without affecting the one at a[0].

There might be a slight complication if you have a mutable object (like a list
or a class instance) as one of f's values, because f and f's copy will have
references to a single copy of that object.  (Same problem, one layer deeper.)
This can be solved by using copy.deepcopy() instead of copy.copy(), which
should recursively copy all of its argument's contents.

Hope that helps...

Jeff Shannon
Technician/Programmer
Credit International





More information about the Python-list mailing list