parsing a dictionary from a string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Benjamin Georgi

    #1

    parsing a dictionary from a string

    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:
    >>s = str(dict_list)
    >>s
    '[{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
    >>dict_list = eval(s)
    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
  • Paul McGuire

    #2
    Re: parsing a dictionary from a string

    "Benjamin Georgi" <georgi@molgen. mpg.dewrote in message
    news:mailman.16 55.1166194994.3 2031.python-list@python.org ...
    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:
    >s = str(dict_list)
    >s
    '[{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.wikis paces.com.)


    from pyparsing import *

    cvtInt = lambda toks: int(toks[0])
    cvtReal = lambda toks: float(toks[0])
    cvtTuple = lambda toks : tuple(toks.asLi st())
    cvtDict = lambda toks: dict(toks.asLis t())

    # define punctuation as suppressed literals
    lparen,rparen,l brack,rbrack,lb race,rbrace,col on = \
    map(Suppress,"( )[]{}:")

    integer = Combine(Optiona l(oneOf("+ -")) + Word(nums))\
    .setName("integ er")\
    .setParseAction ( cvtInt )
    real = Combine(Optiona l(oneOf("+ -")) + Word(nums) + "." +
    Optional(Word(n ums)))\
    .setName("real" )\
    .setParseAction ( cvtReal )
    tupleStr = Forward()
    listStr = Forward()
    dictStr = Forward()

    listItem = real|integer|qu otedString.setP arseAction(remo veQuotes)| \
    Group(listStr) | tupleStr | dictStr

    tupleStr << ( Suppress("(") + Optional(delimi tedList(listIte m)) +
    Optional(Suppre ss(",")) + Suppress(")") )
    tupleStr.setPar seAction( cvtTuple )

    listStr << (lbrack + Optional(delimi tedList(listIte m) +
    Optional(Suppre ss(","))) + rbrack)

    dictEntry = Group( listItem + colon + listItem )
    dictStr << (lbrace + Optional(delimi tedList(dictEnt ry) + \
    Optional(Suppre ss(","))) + rbrace)
    dictStr.setPars eAction( 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.parseSt ring(test)
    print "Result:", result
    for dd in result:
    if isinstance(dd,d ict): 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.1400000000000 001, [2.718,
    'xyzzy', -1.4139999999999 999]]

    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])]




    Comment

    • Peter Otten

      #3
      Re: parsing a dictionary from a string

      Benjamin Georgi wrote:
      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:
      >>s = str(dict_list)
      >>s
      '[{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
      >
      >>dict_list = eval(s)
      >
      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:



      Peter

      Comment

      Working...