No se puede pyparsing Dict () para devolver el diccionario nested

Estoy tratando de analizar cadenas de la forma:

'foo(bar:baz;x:y)' 

Me gustaría que los resultados se devuelvan en forma de un diccionario nested, es decir, para la cadena anterior, los resultados deberían tener este aspecto:

 { 'foo' : { 'bar' : 'baz', 'x' : 'y' } } 

A pesar de las numerosas combinaciones de Dict () y Group (), no puedo hacer que funcione. Mi (una de las versiones de) la gramática se ve así:

 import pyparsing as pp field_name = pp.Word( pp.alphanums ) field_value = pp.Word( pp.alphanums ) colon = pp.Suppress( pp.Literal( ':' ) ) expr = pp.Dict( pp.Group( field_name + \ pp.nestedExpr( content = pp.delimitedList( pp.Group( field_name + colon + field_value ), delim = ';' ) ) ) ) 

Y ahora, los resultados son los siguientes:

 In [62]: str = 'foo(bar:baz;x:y)' In [63]: expr.parseString( str ).asList() Out[63]: [['foo', [['bar', 'baz'], ['x', 'y']]]] In [64]: expr.parseString( str ).asDict() Out[64]: {'foo': ([(['bar', 'baz'], {}), (['x', 'y'], {})], {})} In [65]: print( expr.parseString( str ).dump() ) Out[65]: [['foo', [['bar', 'baz'], ['x', 'y']]]] - foo: [['bar', 'baz'], ['x', 'y']] 

Así que la versión asList() parece bastante buena y debería mostrar un diccionario que estoy asList() creo. Por supuesto, dado que (de la forma en que lo entiendo, corríjame), Dict () analizará las listas de tokens utilizando el primer elemento de la lista como clave y el rest como valores de esa clave en un diccionario. Esto funciona en la medida en que el diccionario no está nested. Por ejemplo, en tal caso:

 expr = pp.Dict( pp.delimitedList( pp.Group( field_name + colon + field_value ), delim = ';' ) ) In [76]: expr.parseString( 'foo:bar;baz:x' ).asDict() Out[76]: {'baz': 'x', 'foo': 'bar'} 

Entonces, la pregunta es ¿qué es lo que está mal con el primer caso (y mi comprensión del problema) o quizás Dict () no puede hacer frente a ese caso? Podría usar asList() y convertirlo manualmente en un diccionario, pero preferiría que lo hiciera en un solo lugar 🙂

Cualquier ayuda o dirección sería muy apreciada.

Gracias.

Dos problemas:

  • Falta un pp.Dict alrededor de pp.delimitedList para hacer que asDict en el resultado interno funcione correctamente
  • Solo está llamando a asDict en la instancia de ParsingResult más ParsingResult , dejando el ParsingResult interno “sin interpretar”

Intenté lo siguiente:

 from pyparsing import * field_name = field_val = Word(alphanums) colon = Suppress(Literal(':')) expr = Dict(Group( field_name + nestedExpr(content = Dict(delimitedList( Group(field_name + colon + field_value), delim = ';' )) ) )) 

Luego lo usé así:

 >>> res = expr.parseString('foo(bar:baz;x:y)') >>> type(res['foo'])  >>> { k:v.asDict() for k,v in res.asDict().items() } {'foo': {'x': 'y', 'bar': 'baz'}}