building lists of dictionaries

Tim Chase python.list at tim.thechases.com
Sun Jul 23 11:57:56 EDT 2006


 > parinfo = [{'value':0., 'fixed':0, 'limited':[0,0], 
'limits':[0.,0.]}]*6
 > parinfo[0]['fixed'] = 1
 > parinfo[4]['limited'][0] = 1
 > parinfo[4]['limits'][0]  = 50.
 >
 > The first line builds a list of six dictionaries with
 > initialised keys.  I expected that the last three lines
 > would only affect the corresponding keys of the
 > corresponding dictionnary and that I would end up with a
 > fully initialised list where only the 'fixed' key of the
 > first dict would be 1, and the first values of limited and
 > limits for dict number 4 would be 1 and 50.
 > respectively....
 >
 > This is not so! I end up with all dictionaries being
 > identical and having their 'fixed' key set to 1, and
 > limited[0]==1 and limits[0]==50.

 > I do not understand this behaviour...

The *6 creates multiple references to the same dictionary.
Thus, when you update the dictionary through one
reference/name (parinfo[0]), the things that the other
entries (parinfo[1:5]) reference that changed dictionary.

You're likely looking for something like

parinfo = [{'value':0., 'fixed':0, 'limited':[0,0], 
'limits':[0.,0.]}]
for i in xrange(1,6): parinfo.append(parinfo[0].copy())

or something like

parinfo = [{'value':0., 'fixed':0, 'limited':[0,0], 
'limits':[0.,0.]}.copy() for i in xrange(0,6)]

However, this will still reference internal lists that have
been referenced multiple times, such that

 >>> parinfo[5]['limited']
[0, 0]
 >>> parinfo[4]['limited'][0] = 2
 >>> parinfo[5]['limited']
[2, 0]

Thus, you'd also want to change it to be something like

parinfo = [
     {'value':0.,
	 'fixed':0,
	 'limited':[0, 0][:],
	 'limits':[0., 0.][:]
      }.copy() for i in xrange(0, 6)]

where the slice operator is used to build a copy of the list
for each element as well (rather than keeping a reference to
the same list for each dictionary).

Hopefully this makes some sense, and helps get you on your
way.

-tkc









More information about the Python-list mailing list