Home > Software design >  Sort dictionary of dictionaries and lists with compound return statement
Sort dictionary of dictionaries and lists with compound return statement

Time:11-08

Does anyone know how to modify this code so that it will sort dictionaries{} and lists[]?

Example sort:

Input: {'a': 1, 'c': 3, 'b': {'b2': 2, 'b1': [1, 7, 4, 2]}}

Output: {'a': 1, 'b': {'b1': [1, 2, 4, 7], 'b2': 2}, 'c': 3}

Original code:

def sort_dict(item: dict):
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

Acknowledgement to @gyli for that wonderful code https://gist.github.com/gyli/f60f0374defc383aa098d44cfbd318eb

These are my two best attempts, but they both fail. In this attempt, I can see v[] getting sorted but the sorted lists aren't making it to the next line where the return is evaluated.

def sort_dict(item: dict):
    for k, v in sorted(item.items()):
        v = sorted(v) if isinstance(v, list) else v
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

The same problem is occurring here, but at least in this attempt I understand why the sorted lists aren't making it to the return statement.

def sort_dict(item: dict):
    return {k: sort_dict(v) if isinstance(v, dict) else sort_list(v) for k, v in sorted(item.items())}

def sort_list(item):
    item = sorted(item) if isinstance(item, list) else item

CodePudding user response:

woo hoo! I figured it out :D I was so close before! Gosh that's exciting

def sort_dict(item: dict):
    for k, v in sorted(item.items()):
        item[k] = sorted(v) if isinstance(v, list) else v
    return {k: sort_dict(v) if isinstance(v, dict) else v for k, v in sorted(item.items())}

CodePudding user response:

Your second answer is nearly close to the correct answer, except for the omissive return value of the function sort_list. Just modify it to

def sort_list(item):
    return sorted(item) if isinstance(item, list) else item

Moreover, you can try to construct a new function for this recursion under different conditions, which is more clear and easy to modify, e.g. if you want to add a string sort functionality

def sort_dict_core(item):
    if isinstance(item, dict):
        return {k: sort_dict_core(v) for k, v in sorted(item.items())}
    elif isinstance(item, list):
        return sorted(item)
    elif isinstance(item, str):
        return sorted(item)
    else:
        return item

def sort_dict(item: dict):
    return {k: sort_dict_core(v)for k, v in sorted(item.items())}

CodePudding user response:

This is another idea; is not the best but working :)

def full_sort(d):
    if type(d) == type({}):
        return {k: full_sort(v) for (k, v) in sorted(d.items())}
    elif type(d) == type([]):
        return sorted(d)
    return d

Output:

{'a': 1, 'b': {'b1': [1, 2, 4, 7], 'b2': 2}, 'c': 3}

Also a compact not readable version:

def fs(d): return {k: fs(v) for (k, v) in sorted(d.items())} if type(
    d) == type({}) else sorted(d) if type(d) == type([]) else d
  • Related