0

I'm trying to sort the JSON dict below. I want to sort the list-of-dict per dict values of both consumers and providers. consumers and providers are each list-of-dict in themselves. They need to be sorted alphabetically.

Here's the dict:

[{'consumers': [{'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}},
   {'label': {'href': '/orgs/1/labels/xx'}}],
  'consuming_security_principals': [],
  'created_by': {'href': '/users/xx'},
  'href': '/orgs/1/sec_policy/draft/rule_sets/yy/sec_rules/xx',
  'ingress_services': [{'href': '/orgs/1/sec_policy/draft/services/xx'}],
  'machine_auth': False,
  'network_type': 'brn',
  'providers': [{'label': {'href': '/orgs/1/labels/xx'}}],
  'resolve_labels_as': {'consumers': ['workloads'],
   'providers': ['workloads']},
  'sec_connect': False,
  'stateless': False,
  'unscoped_consumers': True,
  'update_type': 'create',
  'updated_by': {'href': '/users/xx'}},
 {'consumers': [{'label': {'href': '/orgs/1/labels/xx'}}],
  'consuming_security_principals': [],
  'created_by': {'href': '/users/xx'},
  'href': '/orgs/1/sec_policy/draft/rule_sets/7647/sec_rules/xx',
  'ingress_services': [{'href': '/orgs/1/sec_policy/draft/services/xx'}],
  'machine_auth': False,
  'network_type': 'brn',
  'providers': [{'label': {'href': '/orgs/1/labels/xx'}},
   {'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}],
  'resolve_labels_as': {'consumers': ['workloads'],
   'providers': ['workloads']},
  'sec_connect': False,
  'stateless': False,
  'unscoped_consumers': False,
  'update_type': 'create',
  'updated_by': {'href': '/users/xx'}}]

Tried this, but did not work:

newlist = sorted(list_to_be_sorted, key=lambda k: k['consumers']) 

Output

----> 1 newlist = sorted(d, key=lambda k: k['consumers'])

TypeError: '<' not supported between instances of 'dict' and 'dict'

Need the output as below. With sorted values of consumers and providers alone. Rest of the dict can stay as is. I have tried a couple sorting methods, but it does not work on different value data types

[{'consumers': [{'label': {'href': '/orgs/1/labels/xx'}}, {'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}],
  'consuming_security_principals': [],
  'created_by': {'href': '/users/xx'},
  'href': '/orgs/1/sec_policy/draft/rule_sets/yy/sec_rules/xx',
  'ingress_services': [{'href': '/orgs/1/sec_policy/draft/services/xx'}],
  'machine_auth': False,
  'network_type': 'brn',
  'providers': [{'label': {'href': '/orgs/1/labels/xx'}}],
  'resolve_labels_as': {'consumers': ['workloads'],
   'providers': ['workloads']},
  'sec_connect': False,
  'stateless': False,
  'unscoped_consumers': True,
  'update_type': 'create',
  'updated_by': {'href': '/users/xx'}},
 {'consumers': [{'label': {'href': '/orgs/1/labels/xx'}}],
  'consuming_security_principals': [],
  'created_by': {'href': '/users/xx'},
  'href': '/orgs/1/sec_policy/draft/rule_sets/7647/sec_rules/xx',
  'ingress_services': [{'href': '/orgs/1/sec_policy/draft/services/xx'}],
  'machine_auth': False,
  'network_type': 'brn',
  'providers': [{'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}, {'label': {'href': '/orgs/1/labels/xx'}}],
  'resolve_labels_as': {'consumers': ['workloads'],
   'providers': ['workloads']},
  'sec_connect': False,
  'stateless': False,
  'unscoped_consumers': False,
  'update_type': 'create',
  'updated_by': {'href': '/users/xx'}}]
Vinita Shah
  • 99
  • 12
  • 1
    pretty sure this is a duplicate and this should answer your question: https://stackoverflow.com/questions/72899/how-do-i-sort-a-list-of-dictionaries-by-a-value-of-the-dictionary – DerekG Jul 19 '21 at 18:43
  • 1
    Does this answer your question? [How do I sort a list of dictionaries by a value of the dictionary?](https://stackoverflow.com/questions/72899/how-do-i-sort-a-list-of-dictionaries-by-a-value-of-the-dictionary) – DerekG Jul 19 '21 at 18:43
  • @DerekG I want the outputs for two values consumers and providers. And I have looked at the above, but it does not work on this use-case ``` ----> 1 newlist = sorted(d, key=lambda k: k['providers']) TypeError: '<' not supported between instances of 'dict' and 'dict' ``` – Vinita Shah Jul 19 '21 at 22:48
  • Lists are comparable, but only if their elements are comparable. `consumers` and `providers` both have lists of *dicts* as their values, and you can't compare the dicts in those lists. – chepner Jul 19 '21 at 22:58
  • @chepner I just need them sorted – Vinita Shah Jul 19 '21 at 22:58
  • 1
    Sorted by *what*? Which is "smaller", `[{'label': {'href': '/orgs/1/labels/xx'}}, {'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}]` or `[{'label': {'href': '/orgs/1/labels/xx'}}]`? – chepner Jul 19 '21 at 22:59
  • You can define `[1,2,3] < [4,5]`, because you can compare `1` and `4`. You can't compare `{'label': ...}` and `{'label': ...}`. – chepner Jul 19 '21 at 23:00
  • Sorted alphabetically [{'label': {'href': '/orgs/1/labels/xx'}}, {'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}] Should return [{'ip_list': {'href': '/orgs/1/sec_policy/draft/ip_lists/xx'}}, {'label': {'href': '/orgs/1/labels/xx'}},] – Vinita Shah Jul 19 '21 at 23:01
  • They you have to write a function that compares two dicts by comparing their (only) key to each other. – chepner Jul 19 '21 at 23:02

1 Answers1

0

Got it to work using this logic.

def get_sorted_sec_rules(sec_rules_list):

    for sec_rule in sec_rules_list:
        for sec_rule_key, sec_rule_value in sec_rule.items():
            if sec_rule_key == "consumers":
                sec_rule_value.sort(key=lambda x: list(x.keys())[0])
            if sec_rule_key == "providers":
                sec_rule_value.sort(key=lambda x: list(x.keys())[0])

    return sec_rules_list
Vinita Shah
  • 99
  • 12