By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,660 Members | 1,939 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,660 IT Pros & Developers. It's quick & easy.

Can dictionaries be nested?

P: n/a
I'm parsing some data of the form:

OuterName1 InnerName1=5,InnerName2=7,InnerName3=34;
OuterName2 InnerNameX=43,InnerNameY=67,InnerName3=21;
OuterName3 ....
and so on....

These are fake names I've made up to illustrate the point more clearly.

(the embedded device device can't produce XML and this is what I have
to deal with)

I want to populate a nested set of dictionaries where the outer most
dictionary has look-ups on the OuterNames:

InnerDict = OuterDict["OuterName2"]

Then InnerDict[InnerName3] would yield 21 in the above example.

First, can dictionaries contain dictionaries?

Second, how to create each successive inner dictionary when populating
it? Python doesn't have constructors and (having all of 4 weeks of
Python experience) it isn't clear to me whether in nested while loops
that variables ever go out of scope.

If I do:

OuterDict = {}
while populating dictionaries
InnerDict = {}
while inner stuff to populate
InnerDict["InnerName1"] = 5
.. and so on
:
OuterDict["OuterName1"] = InnerDict

then when I loop around the second time will the same InnerDict get
set back to an empty dictionary and therefore wipe out the dictionary I
put at OuterDict["OuterName1"] ?

I need a new inner dictionary each time thru the outer while loop. It
is not clear to me how to do this.

Jan 12 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
te**********@futurepundit.com writes:
First, can dictionaries contain dictionaries?
Yes.
Second, how to create each successive inner dictionary when populating
it? Python doesn't have constructors and (having all of 4 weeks of
Python experience) it isn't clear to me whether in nested while loops
that variables ever go out of scope.
All variables stay in scope through the entire execution of the
function they're created in.
If I do:

OuterDict = {}
while populating dictionaries
InnerDict = {}
while inner stuff to populate
InnerDict["InnerName1"] = 5
.. and so on
:
OuterDict["OuterName1"] = InnerDict

then when I loop around the second time will the same InnerDict get
set back to an empty dictionary and therefore wipe out the dictionary I
put at OuterDict["OuterName1"] ?
It will get set to a newly created empty dictionary. The old
dictionary won't get wiped out, and will stay accessible through
OuterDict["OuterName1"].
I need a new inner dictionary each time thru the outer while loop. It
is not clear to me how to do this.


You've done it correctly. It's pretty easy to test this stuff by
experiment. You probably spent almost as much time posting to the
newsgroup as simply trying it would have taken:
people = {}
person = {}
person['age'] = 25
person['nationality'] = 'dutch'
people['john'] = person
people {'john': {'nationality': 'dutch', 'age': 25}} person = {} # make new dictionary
people # hasn't changed {'john': {'nationality': 'dutch', 'age': 25}} person['age'] = 3.6e25
person['nationality'] = 'cosmic'
people['FSM'] = person
people {'john': {'nationality': 'dutch', 'age': 25},
'FSM': {'nationality': 'cosmic', 'age': 3.6000000000000002e+25}}

Jan 12 '06 #2

P: n/a
<te**********@futurepundit.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
I'm parsing some data of the form:

OuterName1 InnerName1=5,InnerName2=7,InnerName3=34;
OuterName2 InnerNameX=43,InnerNameY=67,InnerName3=21;
OuterName3 ....
and so on....

I wrote pyparsing for just this kind of job. Using pyparsing, you can both
parse the data and build up structured results - even results with keyed
fields or dictionary-type access.

Here's the complete pyparsing program to parse your data:

---------------------------
data = """
OuterName1 InnerName1=5,InnerName2=7,InnerName3=34;
OuterName2 InnerNameX=43,InnerNameY=67,InnerName3=21;
"""
# or data = file(inputname).read()

from pyparsing import *

EQ = Literal("=").suppress()
SEMI = Literal(";").suppress()
ident = Word(alphas, alphanums+"_")
integer = Word(nums)

value = integer | quotedString

innerentry = Group(ident + EQ + value)

vallist = Dict(delimitedList(innerentry))
outerentry = Group(ident + vallist + SEMI)
datalist = Dict( ZeroOrMore(outerentry) )

vals = datalist.parseString(data)
print vals.keys()
print vals["OuterName1"]["InnerName2"]
print vals.OuterName2.InnerNameY

---------------------------

Prints:
['OuterName2', 'OuterName1']
7
67

Here's the same program, with a few more comments to explain what's going
on:
---------------------------
from pyparsing import *

# define expressions for some basic elements - use pyparsing's basic
# building blocks, Literal and Word
EQ = Literal("=").suppress()
SEMI = Literal(";").suppress()
ident = Word(alphas, alphanums+"_")
integer = Word(nums)

# expand this list to include other items you end up finding in values
value = integer | quotedString

# define the format of the list of InnerName entries
innerentry = Group(ident + EQ + value)

# delimitedList is a pyparsing helper for a list of expressions, separated
by
# some delimiter - default delimiter is a comma
vallist = delimitedList(innerentry)

# lastly, define the overall datalist
outerentry = Group(ident + vallist + SEMI)
datalist = ZeroOrMore( outerentry )

# extract the data into a structure using parseString
vals = datalist.parseString(data)

# prettyprint the results
import pprint
pprint.pprint(vals.asList())
print
# Refinement: have pyparsing build keyed results while
# it parses (accessible like a dict)
vallist = Dict(delimitedList(innerentry))
outerentry = Group(ident + vallist + SEMI)
datalist = Dict( ZeroOrMore(outerentry) )

# reparse using modified grammar
vals = datalist.parseString(data)

# view results using dict functions
print vals.keys()
print vals["OuterName1"]["InnerName2"]

# if keys are valid Python identifiers, can also access results
# like object fields
print vals.OuterName2.InnerNameY
---------------------------
Prints:

[['OuterName1',
['InnerName1', '5'],
['InnerName2', '7'],
['InnerName3', '34']],
['OuterName2',
['InnerNameX', '43'],
['InnerNameY', '67'],
['InnerName3', '21']]]

['OuterName2', 'OuterName1']
7
67

Download pyparsing at http://pyparsing.sourceforge.net. (I'm also making a
couple of pyparsing presentations at PyCon, next month.)

-- Paul
Jan 12 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.