Deep sort list of dict of list (deep nested) with duplicate keys in dict

I am trying to deep sort a list of dict of list with duplicate keys (can go recursively nested) without a specific key to sort on.

Input:

{"payload": [
  {
    "a": {
      "aa": [
        {
          "aa12": {
            "aaa23": 230,
            "aaa21": 210
          }
        },
        {
          "aa11": {
            "aaa12": 120,
            "aaa11": 110
          }
        },
        {
          "aa13": {
            "aaa35": 350,
            "aaa32": 320
          }
        }
      ],
      "aa": [
        {
          "aa12": {
            "aaa22": 22,
            "aaa21": 21
          }
        },
        {
          "aa10": {
            "aaa03": 3,
            "aaa01": 1
          }
        },
        {
          "aa13": {
            "aaa33": 33,
            "aaa32": 32
          }
        },
        {
          "aa1": "aab"
        }
      ],
      "ac": [
        "ac3",
        "ac1",
        "ac2"
      ]
    }
  },
  {
    "b": {
      "bb": [
        "bb4",
        "bb2",
        "bb3",
        "bb1"
      ]
    }
  }
]}

Expected Output:

{"payload": [
  {
    "a": {
      "aa": [
        {
          "aa1": "aab"
        },
        {
          "aa10": {
            "aaa01": 1,
            "aaa03": 3
          }
        },
        {
          "aa12": {
            "aaa21": 21,
            "aaa22": 22
          }
        },
        {
          "aa13": {
            "aaa32": 32,
            "aaa33": 33
          }
        }
      ],
      "aa": [
        {
          "aa11": {
            "aaa11": 110,
            "aaa12": 120
          }
        },
        {
          "aa12": {
            "aaa21": 210,
            "aaa23": 230
          }
        },
        {
          "aa13": {
            "aaa32": 320,
            "aaa35": 350
          }
        }
      ],
      "ac": [
        "ac1",
        "ac2",
        "ac3"
      ]
    }
  },
  {
    "b": {
      "bb": [
        "bb1",
        "bb2",
        "bb3",
        "bb4"
      ]
    }
  }
]}

I have tried using the below recursive method:

ls = {'payload': [{'a': {'aa': [{'aa12': {'aaa23': 230, 'aaa21': 210}}, {'aa11': {'aaa12': 120, 'aaa11': 110}}, {'aa13': {'aaa35': 350, 'aaa32': 320}}], 'ac': ['ac3', 'ac1', 'ac2'], 'aa': [{'aa12': {'aaa22': 22, 'aaa21': 21}}, {'aa10': {'aaa03': 3, 'aaa01': 1}}, {'aa13': {'aaa33': 33, 'aaa32': 32}, {"aa1": "aab"}}]}}, {'b': {'bb': ['bb4', 'bb2', 'bb3', 'bb1']}}]}
output = sorted_deep(ls)
print(output)

def sorted_deep(d):
  if isinstance(d,list):
    return sorted(sorted_deep(v) for v in d)
  if isinstance(d,dict):
    return {k: sorted_deep(d[k]) for k in sorted(d)}
  return d

But this ain't working. It overrides the duplicate key's value with the last found value when it sorts. Since the duplicate key can be any string, we can't iterate by specifying the key name. I'm looking for a generic solution which sorts any given complex list of dicts with nested list/dicts.

My end goal is to deep match 2 such JSON's to find the differences.

1 answer

  • answered 2020-01-18 11:41 Giorgi Beria

    Consider using sorted()

    sorted(paymentsByAgreeement[agreement['agreementId']],key=lambda i: 
    (i['eventDate'],i['id']))
    

    read about sorted and lambda here https://wiki.python.org/moin/HowTo/Sorting with lambda, you can access child elements to go deeper you may need a for and another lambda with sorted