Próbuję analizować ciągi w postaci:Can not Get pyparsing Dict(), aby powrócić zagnieżdżone słownika
'foo(bar:baz;x:y)'
Chciałbym wyniki mają być zwracane w postaci zagnieżdżonego słownika, czyli dla powyższego napisu, wyniki powinny wyglądać następująco:
{ 'foo' : { 'bar' : 'baz', 'x' : 'y' } }
Pomimo licznych kombinacjach Dict() i Grupy() nie mogę zmusić go do pracy. My (jedna z wersji) gramatyka wygląda następująco:
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 = ';'
)
)
)
)
i teraz, wyniki są następujące:
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']]
Więc wersja asList()
wygląda całkiem dobre dla mnie i powinna przynieść słownika Poszukuję. Oczywiście biorąc pod uwagę to (sposób, w jaki to rozumiem, proszę poprawić) Dict() przeanalizuje listy tokenów, używając pierwszego elementu listy jako klucza, a resztę jako wartości tego klucza w słowniku. Działa to, o ile słownik nie jest zagnieżdżony. Na przykład w takim przypadku:
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'}
Więc pytanie jest, co jest złego w pierwszym przypadku (i mojego zrozumienia problemu) czy może Dict() nie może poradzić sobie z takim przypadku? Mógłbym użyć asList()
i przekonwertować to ręcznie do słownika, ale wolałbym, żeby to zrobiło pypars :)
Każda pomoc lub wskazówki będą mile widziane.
Dziękuję.
Niezły chwyt na brakującej 'pp.Dict'. Spróbuj także wydrukować 'res.dump()', aby zobaczyć zagnieżdżone klucze i wartości. (Ponieważ 'res' jest obiektem ParseResults, będzie obsługiwał zagnieżdżony dostęp w stylu Dict bez konwersji za pomocą asDict:' res ['foo'] ['x'] 'daje 'y' lub możesz użyć notacji z kropkami jako o ile klucze są ładne, identyfikatory Pythona: 'res.foo.bar' daje 'baz'.) – PaulMcG
Witam @Paul, miło otrzymuję komplement od samego autora :) Znajduję' res.dump() 'niewiele więcej informacji niż "str (res)", ale może po prostu nie wiem jak to interpretować? Nigdy nie używam pyparsingów, powinienem powiedzieć. –
Dziękuję bardzo Niklas! Nie wiedziałem, że w wynikach są również instancje ParseResults, myślałem, że będą już listami lub dyktami. Paul - dzięki za wskazówkę, jak używać dicta bez konwersji, może się to przydać w tym, nad czym pracuję! :) – kgr