Home > Mobile >  Sort list of dictionaries according to custom ordering
Sort list of dictionaries according to custom ordering

Time:03-30

I need to sort list of dictionaries according to predefined list of values

I am using this part of code, and it will work fine but l_of_dicts has values which are not in a sort_l(predefined list of values)

l_of_dicts = [{'name':'Max','years':18},{'name':'John','years':25},{'name':'Ana','years':19},{'name':'Melis','years':38},{'name':'Ivana','years':38}]

sort_l = ['Ana','Melis','John','Max','Peter']

res = sorted(l_of_dicts , key = lambda ele: sort_l .index(list(ele.values())[0]))

I get an error :

ValueError: 'Ivana' is not in list

Is it posible to ignore that values? or even better extract them to another list?

CodePudding user response:


The script bellow does the job but looks heavier than it should be. Maybe there's easier way to do it.

Script:

def sort_dict_list(dict_list, sorting_list):
    result = []
    not_used_values = []
    temp = {}
    for index, dictionary in enumerate(dict_list):
        temp[dictionary['name']] = index
    for item in sorting_list:
        if item in temp.keys():
            result.append(dict_list[temp[item]])
        else:
            not_used_values.append(item)
    return result, not_used_values

CodePudding user response:

You could do some preprocessing to store the ordering of only names in l_of_dicts:

l_of_dicts = [{'name': 'Max', 'years': 18}, {'name': 'John', 'years': 25},
              {'name': 'Ana', 'years': 19}, {'name': 'Melis', 'years': 38}]
names_in_dicts = {d['name'] for d in l_of_dicts if 'name' in d}
sort_l = ['Ana', 'Melis', 'Ivana', 'John', 'Max', 'Peter']
sort_order = {name: order for order, name in enumerate(sort_l) if name in
              names_in_dicts}
print(sort_order)  # {'Ana': 0, 'Melis': 1, 'John': 3, 'Max': 4}
sorted_l_of_dicts = sorted(l_of_dicts, key=lambda d: sort_order[d['name']])
print(sorted_l_of_dicts)  # [{'name': 'Ana', 'years': 19}, {'name': 'Melis', 'years': 38}, {'name': 'John', 'years': 25}, {'name': 'Max', 'years': 18}]
  • Related