[Tutor] Inserting one dictionary into another

spir denis.spir at free.fr
Fri Jan 2 13:07:14 CET 2009


On Thu, 01 Jan 2009 11:04:42 -0500
"Keith Reed" <keith_reed at fastmail.net> wrote:

> I'm having trouble assigning a dictionary as a value within another:
> 
> 
> -------- Code Snippet Start --------
> 
>         for line in fromchild.readlines():
>                 itemarray = line.strip().split(":")
>                 parentdictkey = itemarray[0]
>                 print 'parentdictkey = ' + parentdictkey
>                 for index in range(len(headerinfo)):
>                         nesteddict[headerinfo[index]] = itemarray[index]
>                 #print nesteddict
>                 parentdict[parentdictkey] = nesteddict
>                 nesteddict.clear()
>         print
>         '-------------------------------------------------------------------------\n'
>         print parentdict
> 
> -------- Code Snippet End --------
> 
> -------- Output Start --------
> {'24': {}, '25': {}, '26': {}, '27': {}, '20': {}, '21': {}, '22': {},
> '23': {}, '28': {}, '29': {}, '1': {}, '0': {}, '3': {}, '2': {}, '5':
> {}, '4': {}, '7': {}, '6': {}, '9': {}, '8': {}, '11': {}, '10': {},
> '13': {}, '12': {}, '15': {}, '14': {}, '17': {}, '16': {}, '19': {},
> '18': {}, '31': {}, '30': {}}
> -------- Output End --------

Some notes about the code.
-1- 'itemarray' actually is a list of data items, right? So why not simply call it 'items'?

-2- It seems that 'headerinfo' is a constant list of data field names, that will become (nested)
dict keys. If it really is constant, I would thus call it 'KEYS', else 'keys' if it is as computed
value instead (e.g. read from a file/table header).

-3- As headerinfo/keys is constant /inside the dict filling loop/ anyway, you can use nice
built-in functions enumerate() or zip() to make the code much clearer. Below how they work/

-4- 'parentdictkey' is a rather misleading name as I understand it -- isn't it the key of the
current nested dict instead?

=========================================
keys = ("un","du","tri")
items= ("foo","bar","blah")

d=dict()
for index,key in enumerate(keys):	# --> (index,item) tuples
	d[key]=items[index]
print d

d.clear()
for key,item in zip(keys,items):	# --> (key,item) tuples
	d[key]=item
print d
==>
{'tri': 'blah', 'du': 'bar', 'un': 'foo'}
{'tri': 'blah', 'du': 'bar', 'un': 'foo'}
=========================================

So that your nested dict filling loop may change:
	for index in range(len(headerinfo)):
		nesteddict[headerinfo[index]] = itemarray[index]
	for key,item in zip(keys,items):
		nesteddict[key] = item

> The key looks correct below (it's a unique ID), but the dictionary
> inserted below is empty.
> If I uncomment the print statement above, the nesteddict dictionary
> displays all the proper keys and values. So I know it's getting filled
> OK, but it doesn't insert into the parent dictionary at all in the line:
> parentdict[parentdictkey] = nesteddict
> 
> Any thoughts on how to properly insert the nested dictionary so that I
> can refer to it?
> 

The point (always again biting python users) is that you have created a single nesteddict object.
And: Python variables simply are name:object bindings -- which is right. So that at the end of
your routine, you have a single nesteddict which happens to be empty because you clear it. All
parentdict[parentdictkey] references point to a unique object, actually an empty dictionay.
The right thing to do is to create a brand new dict at start of each loop -- which by the way is
fully consistent because you really n sub-dictionaries:
	for line in fromchild.readlines():
		nested_dict = dict()	# new empty sub-dict
Then you do not need the final clear()ing anymore.

Denis
------
la vida e estranya


More information about the Tutor mailing list