обрезать json на основе совпадающих ключей с помощью python

#python #json

#python #json

Вопрос:

У меня есть JSON, в котором я пытаюсь обрезать, если соответствует определенным критериям. Ниже приведен мой JSON:

 {'Items': [
    {'type': 'track', 'event': 'flag', 'properties': {'old': 'ABC11001'
        }, 'options': {'target': 'unflag'
        }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603043772959
        }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
        }, 'traits': {'lfid': 'foobar'
        }, 'id': '40cfb8a0-116b-11eb-9635-df40a485d353', 'id': 'footer', 'partner_resid': '934591a0-e05d-dd62-a55a-sh1735ec3981'
    },
    {'type': 'track', 'event': 'next', 'properties': {'old': 'ABC110023', 'new': 'ABC110026'
        }, 'options': {'target': 'nextTop'
        }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603043943118
        }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
        }, 'traits': {'lfid': 'foobar'
        }, 'id': 'a63ab410-116b-11eb-83a1-99c63d9410bc', 'lfid': 'foobar', 'partner_resid': '934591a0-e05d-dd62-a55a-sh1735ec3981'
    },
    {'type': 'track', 'event': 'flag', 'properties': {'old': 'ABC110099'
        }, 'options': {'target': 'unflag'
        }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603043137542
        }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
        }, 'traits': {'lfid': 'foobar'
        }, 'id': 'c6116880-1169-11eb-9880-c39a5007644a', 'lfid': 'foobar', 'partner_resid': '934591a0-e05d-dd62-a55a-sh1735ec3981'
    },
    {'type': 'track', 'event': 'flag', 'properties': {'new': 'ABC002234'
        }, 'options': {'target': 'flag'
        }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603042870105
        }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
        }, 'traits': {'lfid': 'foobar'
        }, 'id': '26a94d80-1169-11eb-9880-c39a5007644a', 'lfid': 'foobar', 'partner_resid': '934591a0-e05d-dd62-a55a-sh1735ec3981'
    },
    {'type': 'track', 'event': 'active', 'properties': {'new': 'ABC883322'
        }, 'options': {'target': 'bottomNext'
        }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603037276643
        }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
        }, 'traits': {'lfid': 'foobar'
        }, 'id': '20b1aab0-115c-11eb-9e18-b5713e730a08', 'lfid': 'foobar', 'partner_resid': '958791a0-e05d-4e01-a55a-da48e3ec3981'
    },
  }
  

Здесь я пытаюсь фильтровать с event помощью having active и properties только с new помощью, но не получается:
Ниже приведен мой код:

     for idx, elem in enumerate(json_result['Items']):
        
        if json_result.get("Items").get("elem").properties.get("old") in elem.keys():
            del json_result['Items'][idx]
  

Не уверен, где я делаю неправильно

result_json должен содержать только:

         {'type': 'track', 'event': 'active', 'properties': {'new': 'ABC883322'
            }, 'options': {'target': 'bottomNext'
            }, 'userId': None, 'anonymousId': 'c7ccc67e-f7d4-4198-9cef-7d6895c1bd3b', 'meta': {'timestamp': 1603037276643
            }, '_': {'originalAction': 'track', 'called': 'track', 'from': 'engineEnd'
            }, 'traits': {'lfid': 'foobar'
            }, 'id': '20b1aab0-115c-11eb-9e18-b5713e730a08', 'lfid': 'foobar', 'partner_resid': '958791a0-e05d-4e01-a55a-da48e3ec3981'}
  

Комментарии:

1. Одна вещь заключается в том, что вы не проверяете, что ключ ‘event’ имеет значение ‘active’.

2. Я почти уверен if , что оператор не выполняет то, что вы хотите, чтобы он делал … код пытается получить доступ к вложенному словарю properties по атрибуту elem.properties , который не будет существовать, потому что вы не можете получить доступ к ключам словаря по атрибуту в Python. Правильный способ сделать это — по индексу elem["properties"] или через elem.get("properties") . Еще одна проблема заключается в конце инструкции. Он проверяет, находится ли присвоенное значение elem["properties"]["old"] в elem.keys() , но, учитывая примеры, которые вы нам предоставили, этого никогда не произойдет

Ответ №1:

у вас есть ошибка в вашем json (отсутствует закрывающая скобка списка) -> если я правильно понимаю, вы хотите отфильтровать только те объекты из списка json, которые имеют event=active ключ and "new" in properties . Почему бы не создать новый список результатов и сохранить там только совпадающие объекты.

 items = dct["Items"]
result = []
for obj in items:
    if obj["event"] == "active" and "new" in obj["properties"]:
        result.append(obj)