dev740
dev740

Reputation: 121

How to compare every value in JSON response and filter them based on some condition in python?

I have a JSON response which looks like this

response = {
   "detections":[
      {
         "label":"apple",
         "x":50,
      },
      {
         "label":"apple",
         "x":55,
      },
      {
         "label":"apple",
         "x":500,
      },
      {
         "label":"banana",
         "x":352,
      }
   ]
}

I want to filter this response such that, the values where the labels are same filter out if the absolute difference between them is less than 10, otherwise keep both the responses

So I want the final result to be like this

updated_response = {
             "detections":[
                {
                   "label":"apple",
                   "x":50,
                },
                {
                   "label":"apple",
                   "x":500,
                },
                {
                   "label":"banana",
                    "x":352,
                }
             ]
          } 

The second value where x=55 is removed because the absolute difference between them is less than 10, but third value with x=500 is included because the absolute difference is more than 10

Any idea how I can achieve this?

Upvotes: 0

Views: 122

Answers (1)

CryptoFool
CryptoFool

Reputation: 23089

Here's my take on your solution, not trying to use any fancy list comprehensions or trying to limit the number of lines I use, but instead keeping things simple and hopefully easy to understand:

from collections import defaultdict
import json

response = {
   "detections":[
      {
         "label":"apple",
         "x":50,
      },
      {
         "label":"apple",
         "x":55,
      },
      {
         "label":"apple",
         "x":500,
      },
      {
         "label":"banana",
         "x":352,
      }
   ]
}

# Build a dictionary where the keys are labels and the values
# are lists with the x values for that label
labels = defaultdict(list)
for item in response['detections']:
    label = item['label']
    x = item['x']
    labels[label].append(x)

# Sort each of the lists (the values) in the dictionary we created
for label in labels:
    labels[label] = sorted(labels[label])

# Now for each of the labels in our dictionary...
for label in labels:
    # Get a reference to the list of 'x' values for this label
    l = labels[label]
    # Walk backwards across the list of label 'x' values...
    for i in range(len(l)-1, 0, -1):
        # If the current value is 10 units or less from the next (prior?) value,
        # then remove the current value
        if l[i] - l[i-1] <= 10:
            del l[i]

# Now create a list of items that looks like the list in original data
r = []
for label in labels:
    for x in labels[label]:
        r.append({"label": label, "x": x})

# Wrap the list in a dictionary like in the original data
updated_response = {'detections':r}

# Show the resulting dictionary as pretty JSON
print(json.dumps(updated_response, indent=4))

Result:

{
    "detections": [
        {
            "label": "apple",
            "x": 50
        },
        {
            "label": "apple",
            "x": 500
        },
        {
            "label": "banana",
            "x": 352
        }
    ]
}

I think the only slightly clever thing here is to walk each list backwards when doing the deletion. This is a common trick to use when you'll be deleting items. It basically means that the location of any item will only change after it's been considered. Walking through the list in the forward direction isn't as easy.

Upvotes: 3

Related Questions