How to filter a JSON?

Good day community,

Maybe someone could recommend the best way how to filter a JSON output? I’ve made an API request to the server and got a reply:

[
  {
    "Id": 111111,
    "description": [
      {
        "criteria": "Cache",
        "measurement": null,
        "comlexName": null,
        "value": "32MB",
        "criteriaId": 907,
        "valueId": null,
        "comlexId": null,
        "lastUpdateDate": "2021-03-23T11:09:32.293"
      }
    ]
  }
]

How can I get only certain keys? In this example I’m interested in “criteria” and “value”

Thank you in advance :slight_smile:

My rough attempt without testing, using pattern matching


match reply:

     case [{"description": {"criteria": str() as criteria, "value“: str() as value}]:
          print(criteria, value)

That will get you the first criteria and value if you have a list holding a dictionary with key description whose value is a dict with keys criteria and value whose values are str…I think

A better way might be


for entry in reply:
    match entry:
        case {"description": {"criteria": str() as criteria, "value": str() as value}:
            print(criteria, value)
1 Like

I am pretty new to match-case so I was curious which exact form works. Here is the code by @Melendowski made into runnable code (it is not necessary to use the keyword as):

Input data (click to show)
null = None
reply = [
  {
    "Id": 111111,
    "description": [
      {
        "criteria": "Cache",
        "measurement": null,
        "comlexName": null,
        "value": "32MB",
        "criteriaId": 907,
        "valueId": null,
        "comlexId": null,
        "lastUpdateDate": "2021-03-23T11:09:32.293"
      }
    ]
  }
]
match reply:
     case [
             {"description": [
                 {"criteria": str(criteria), "value": str(value)}
             ]}]:
          print(criteria, value)
Cache 32MB

As John wrote, you would probably want to iterate the the list items in for loops.

2 Likes

Thank you all for your reply!

What if I have multiple blocks, like:

 [{'productId': 1111111, 'description': [
            {
                'criteria': 'Cache',
                'measurement': None,
                'comlexName': None, 
                'value': '32MB', 
                'orderNo': '10', 
                'criteriaId': 907, 
                'valueId': None, 
                'comlexId': None, 
                'lastUpdateDate': '2021-03-23T11:09:32.293'
            }, 
            {
                'criteria': 'Code', 
                'measurement': None, 
                'comlexName': None, 
                'value': 'UPS', 
                'orderNo': '999', 
                'criteriaId': 999, 
                'valueId': None, 
                'comlexId': None, 
                'lastUpdateDate': '0001-01-01T00:00:00'
            },
            {
                'criteria': 'Speed', 
                'measurement': 'MHz', 
                'comlexName': None, 
                'value': '3700', 
                'orderNo': '6', 
                'criteriaId': 906, 
                'valueId': None, 
                'comlexId': None, 
                'lastUpdateDate': '2021-03-23T11:09:32.293'
            } ]}]

I had tried what you suggested, but it didn’t output anything.

That is the correct behaviour. The number of list items in the case pattern must match the number of list items in the data. Demonstration:

test_lists = (
    ['Crusoe'],
    ['Holmes', 'Watson'],
    )

for test_list in test_lists:
    print(f'--- testing {test_list}, all matches:')
    match test_list:
        case [a]:
            print(f'One item list match: {a!r}')
    match test_list:
        case [a, b]:
            print(f'Two items list match: {a!r}, {b!r}')
    print()
--- testing ['Crusoe'], all matches:
One item list match: 'Crusoe'

--- testing ['Holmes', 'Watson'], all matches:
Two items list match: 'Holmes', 'Watson'

So, as John suggested and provided example: iterate the list.

Extract it from your data:

...
     case [{"description": list(descriptions_list)}]:
        ...

…and iterate it using for. In the loop use another match statement to extract the data from the individual items.

1 Like