Json разбор с пунктирной линией в python - PullRequest
0 голосов
/ 18 февраля 2020

Имеется ли какая-либо библиотека python (PyPI), из которой я могу проанализировать json с:

1.  dot separated path
2.  order independant in case of array

Данные:

  "attr1": [
    {
      "attr2": "val2"
    },
    {
      "attr3": {
        "attr4": "val4"
      }
    }
  ]
}

Здесь у меня есть путь такие как 'attr1.attr3.attr4'. Из которого мне нужно получить значение 'val4'. При использовании библиотеки Dotty DICT, я должен указать положение для массива: 'attr1.1.attr3.attr4'. Но положение может меняться. Вполне возможно, что 'attr3' стоит на первом месте в 'attr1'.

Итак, есть ли какая-либо библиотека, которая может предоставить

1.  'val4' when I pass 'attr1.attr3.attr4' path  (Not 'attr1.1.attr3.attr4')
2.  'val2' when I pass 'attr1.attr2' (Not 'attr1.0.attr2')

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Я создал функцию, которая будет анализировать строку, которую вы предоставляете, с объектом словаря. Надеюсь, это поможет вам.

Преимущество здесь в том, что вы никогда не анализируете весь словарь и просто получаете требуемые значения. например, если вы хотите получить доступ к 4 ключам, разделенным ., сложность будет равна 4. Он всегда будет возвращать результат в o (n), где n - количество ключей.

def get_value(dotted_str, dict_obj):
    names = dotted_str.split('.')
    current_level = dict_obj
    for index, name in enumerate(names):
        if index:
            if isinstance(current_level, list):
                current_level = current_level[int(name)]
            else:
                current_level = current_level[name]
    return current_level


a_dict = {"a": {"this": 100, "is": 500, "nested": [{"first": 0}, {"second": ["I", "am", "list"]}]}, "b": [1, 2, 3, 4]}
get_value("a_dict.a.nested.1.second", a_dict)

Вывод код выше:

['I', 'am', 'list']
0 голосов
/ 18 февраля 2020
  • вы можете рекурсивно проверить, является ли это list или dict. И генерировать ключ в зависимости от того, является ли это dict или list.
  • Это хакерское решение, и я не знаю, будет ли это работать для вашего случая. Но вот моя лучшая попытка.
d = {
    "attr1": [
    {
      "attr2": "val2"
    },
    {
      "attr3": {
        "attr4": "val4"
      }
    }
  ]
}

l = dict()
def foo(x, z):
    if isinstance(x, list):
        for val in x:
            foo(val, z)
    elif isinstance(x, dict):
        for k,v in x.items():
            foo(v, z+"."+k)
    else:
        l[z[1:]] = x


foo(d, "")

print(l['attr1.attr2'])
print(l['attr1.attr3.attr4'])
  • output

val2
val4

...