Can#39;t get pyparsing Dict() to return nested dictionary(无法让 pyparsing Dict() 返回嵌套字典)
问题描述
我正在尝试解析以下形式的字符串:
'foo(bar:baz;x:y)'我希望以嵌套字典的形式返回结果,即对于上述字符串,结果应如下所示:
{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }
尽管有多种 Dict() 和 Group() 组合,但我无法让它工作.我的(版本之一)语法如下所示:
导入pyparsing为ppfield_name = pp.Word( pp.alphanums )field_value = pp.Word( pp.alphanums )冒号 = pp.Suppress( pp.Literal( ':' ) )expr = pp.Dict(pp.Group(字段名称 + pp.nestedExpr(内容 = pp.delimitedList(pp.Group( field_name + 冒号 + field_value ),德利姆 = ';'))))
现在,结果如下:
In [62]: str = 'foo(bar:baz;x:y)'在 [63]: expr.parseString( str ).asList()出[63]: [['foo', [['bar', 'baz'], ['x', 'y']]]]在 [64]: expr.parseString( str ).asDict()Out[64]: {'foo': ([(['bar', 'baz'], {}), (['x', 'y'], {})], {})}在 [65]: 打印(expr.parseString(str).dump())输出[65]: [['foo', [['bar', 'baz'], ['x', 'y']]]]- foo: [['bar', 'baz'], ['x', 'y']]
所以 asList()
版本对我来说看起来很不错,应该会产生一个我想要的字典.当然,鉴于(以我的理解方式,请纠正我)Dict() 将通过使用列表的第一个元素作为键并将其余所有元素作为字典中该键的值来解析标记列表.这适用于字典未嵌套的情况.例如在这种情况下:
expr = pp.Dict(pp.delimitedList(pp.Group( field_name + 冒号 + field_value ),德利姆 = ';'))在 [76]: expr.parseString( 'foo:bar;baz:x' ).asDict()出[76]:{'baz':'x','foo':'bar'}
那么,问题是第一种情况(以及我对问题的理解)有什么问题,或者 Dict() 无法应对这种情况?我可以使用 asList()
并将其手动转换为字典,但我宁愿让 pyparsing 来做 :)
任何帮助或指导将不胜感激.
谢谢.
解决方案两个问题:
- 您在
pp.delimitedList
周围缺少一个 pp.Dict
以使 asDict
在内部结果上正常工作 - 您只在最外层的
ParsingResult
实例上调用 asDict
,而使内部的 ParsingResult
保持未解释"
我尝试了以下方法:
from pyparsing import *field_name = field_val = Word(字母数字)冒号 = Suppress(Literal(':'))expr = 字典(组(字段名称 +嵌套Expr(内容=字典(分隔列表(组(字段名称 + 冒号 + 字段值),德利姆 = ';')))))
然后像这样使用它:
<预><代码>>>>res = expr.parseString('foo(bar:baz;x:y)')>>>类型(res ['foo'])<class 'pyparsing.ParseResults'>>>>{ k:v.asDict() for k,v in res.asDict().items() }{'foo': {'x': 'y', 'bar': 'baz'}}
I'm trying to parse strings of the form:
'foo(bar:baz;x:y)'
I'd like the results to be returned in form of a nested dictionary, i.e. for the above string, the results should look like this:
{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }
Despite numerous combinations of Dict() and Group() I can't get it to work. My (one of the versions of) grammar looks like this:
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 = ';'
)
)
)
)
and now, the results are as follows:
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']]
So the asList()
version looks quite good to me and should yield a dictionary I'm after I think. Of course given that (the way I understand it, please correct me) Dict() will parse lists of tokens by using the first element of the list as a key and all the rest as values of that key in a dictionary. This works insofar the dictionary is not nested. For example in such case:
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'}
So, the question is what is wrong with the first case (and my understanding of the problem) or perhaps Dict() can't cope with such case? I could use asList()
and convert that manually into a dictionary, but I'd rather have pyparsing do it :)
Any help or directions would be greately appreciated.
Thank you.
Two problems:
- You are missing a
pp.Dict
aroundpp.delimitedList
to makeasDict
on the inner result work correctly - You are only calling
asDict
on the outermostParsingResult
instance, leaving the innerParsingResult
"uninterpreted"
I tried the following:
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 = ';'
))
)
))
Then used it like this:
>>> res = expr.parseString('foo(bar:baz;x:y)')
>>> type(res['foo'])
<class 'pyparsing.ParseResults'>
>>> { k:v.asDict() for k,v in res.asDict().items() }
{'foo': {'x': 'y', 'bar': 'baz'}}
这篇关于无法让 pyparsing Dict() 返回嵌套字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!