parsing a dictionary from a string

B

Benjamin Georgi

Hello list,

I could use some help extracting the keys/values of a list of
dictionaries from a string that is just the str() representation of the
list (the problem is related to some flat file format I'm using for file
IO).

Example:'[{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]'

Then, what I want to do is to reconstruct dict_list given s.
Now, one possible solution would be

but since the content of s cannot be blindly trusted I`d rather not do
it that way. Basically my question is whether there is another solution
which is simpler than using regular expressions.

Best,
Benjamin
 
P

Paul McGuire

Benjamin Georgi said:
Hello list,

I could use some help extracting the keys/values of a list of dictionaries
from a string that is just the str() representation of the list (the
problem is related to some flat file format I'm using for file IO).

Example:'[{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]'
Pyparsing comes with a working example that will parse strings representing
lists, even if they are nested. This is actually more complex than the
example you've given - none of your lists is nested. Here is that example,
adapted to handle dict elements, too.

-- Paul
(The pyparsing home page/wiki is at pyparsing.wikispaces.com.)


from pyparsing import *

cvtInt = lambda toks: int(toks[0])
cvtReal = lambda toks: float(toks[0])
cvtTuple = lambda toks : tuple(toks.asList())
cvtDict = lambda toks: dict(toks.asList())

# define punctuation as suppressed literals
lparen,rparen,lbrack,rbrack,lbrace,rbrace,colon = \
map(Suppress,"()[]{}:")

integer = Combine(Optional(oneOf("+ -")) + Word(nums))\
.setName("integer")\
.setParseAction( cvtInt )
real = Combine(Optional(oneOf("+ -")) + Word(nums) + "." +
Optional(Word(nums)))\
.setName("real")\
.setParseAction( cvtReal )
tupleStr = Forward()
listStr = Forward()
dictStr = Forward()

listItem = real|integer|quotedString.setParseAction(removeQuotes)| \
Group(listStr) | tupleStr | dictStr

tupleStr << ( Suppress("(") + Optional(delimitedList(listItem)) +
Optional(Suppress(",")) + Suppress(")") )
tupleStr.setParseAction( cvtTuple )

listStr << (lbrack + Optional(delimitedList(listItem) +
Optional(Suppress(","))) + rbrack)

dictEntry = Group( listItem + colon + listItem )
dictStr << (lbrace + Optional(delimitedList(dictEntry) + \
Optional(Suppress(","))) + rbrace)
dictStr.setParseAction( cvtDict )

tests = """['a', 100, ('A', [101,102]), 3.14, [ +2.718, 'xyzzy', -1.414] ]
[{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]"""

for test in tests.split("\n"):
print "Test:", test.strip()
result = listStr.parseString(test)
print "Result:", result
for dd in result:
if isinstance(dd,dict): print dd.items()
print



Prints:
Test: ['a', 100, ('A', [101,102]), 3.14, [ +2.718, 'xyzzy', -1.414] ]
Result: ['a', 100, ('A', [101, 102]), 3.1400000000000001, [2.718,
'xyzzy', -1.4139999999999999]]

Test: [{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]
Result: [{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]
[(0, [2]), (1, [])]
[(0, []), (1, []), (2, [])]
[(0, [1, 2])]
 
P

Peter Otten

Benjamin said:
I could use some help extracting the keys/values of a list of
dictionaries from a string that is just the str() representation of the
list (the problem is related to some flat file format I'm using for file
IO).

Example:'[{0: [2], 1: []}, {0: [], 1: [], 2: []}, {0: [1, 2]}]'

Then, what I want to do is to reconstruct dict_list given s.
Now, one possible solution would be

but since the content of s cannot be blindly trusted I`d rather not do
it that way. Basically my question is whether there is another solution
which is simpler than using regular expressions.

Michael Spencer has published a simple eval() that only allows constant
expressions:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/364469

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top