Can dictionaries be nested?
Paul McGuire
ptmcg at austin.rr._bogus_.com
Thu Jan 12 05:40:00 EST 2006
<techiepundit at futurepundit.com> wrote in message
news:1137034480.396463.296560 at g47g2000cwa.googlegroups.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
More information about the Python-list
mailing list