Custom Python Sorting Dictionary

So, I have a dictionary that looks like this when I type it:

{'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} 

I want to sort them out as I see fit. Suppose I want it to be sorted (by key): ZT21, 10, WX21, UM, 5, 2 .

Does anyone know how to sort a dictionary in a predefined / user-defined way? What I am doing is getting this dictionary from the database, and it can contain more than 20 keys, each of which has a specific order. The order is always set, but sometimes certain keys / values ​​will not be in the dictionary. So this can also happen:

 {'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} 

sorted (by key): ZT21, 10, WX21, UM, 5, 2 .

So 10 in this example is missing, but the sorting I need remains the same, 10 would simply be missing.

Any ideas?

+8
source share
5 answers

Python dictionaries are unordered. You can get the desired results in the form of list

 >>> d = {'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25} >>> keyorder = ['ZT21', '10', 'WX21', 'UM', '5', '2'] >>> sorted(d.items(), key=lambda i:keyorder.index(i[0])) [('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)] 

or as an OrderedDict

 >>> from collections import OrderedDict >>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.index(i[0]))) OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]) 

If you do a lot of them, it will be more efficient to use a dict for the keyword

 >>> keyorder = {k:v for v,k in enumerate(['ZT21', '10', 'WX21', 'UM', '5', '2'])} >>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.get(i[0]))) OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]) 
+27
source

You can not. Use collections.OrderedDict instead.

+2
source

Dictionaries are inherently disordered, so you cannot sort the dictionary directly. You can sort key / value pairs by sorting someDict.items() and passing the key function in the same way as when sorting something else, but you will get a sorted list, not a dictionary. See Previous questions about sorting dictionaries: Python: sorting a dictionary of lists and sorting a dictionary by key length, for example.

+1
source

You can sort it using OrderedDict and specifying your order.

 def customsort(dict1 , key_order): items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] sorted_dict = OrderedDict() for i in range(len(key_order)): sorted_dict[key_order[i]] = items[i] return sorted_dict key_order = [ "monday" ,"tuesday" ,"wednesday" ,"thursday" ,"friday" ,"saturday"] dict1 ={"monday" : 10 , "thursday" :12 , "wednesday" : 34} sorted_dicti = customsort(dict1,key_order) print(sorted_dicti) 

customsort () sorts this dictionary (dict1) in order (key_order) passed by the user.

 items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 

It will check if the given key is in dict1, if it is there, then it will put the value specified in dict1, otherwise it will set the value to 0.

 OrderedDict([('monday', 10), ('tuesday', 0), ('wednesday', 34), ('thursday', 12), ('friday', 0), ('saturday', 0)]) 
+1
source

I had exactly the same problem and developed a lightweight general solution:

 from collections import OrderedDict def make_custom_sort(orders): orders = [{k: -i for (i, k) in enumerate(reversed(order), 1)} for order in orders] def process(stuff): if isinstance(stuff, dict): l = [(k, process(v)) for (k, v) in stuff.items()] keys = set(stuff) for order in orders: if keys.issuperset(order): return OrderedDict(sorted(l, key=lambda x: order.get(x[0], 0))) return OrderedDict(sorted(l)) if isinstance(stuff, list): return [process(x) for x in stuff] return stuff return process 

First you create an instance of a custom order sort function:

 custom_sort = make_custom_sort([ ['ZT21', '10', 'WX21', 'UM', '5', '2'] ]) 

Now, the actual sort:

 result = custom_sort(my_dataset) 

Missing keys at the end are rejected in an unspecified order. Note that this closure is recursive. As indicated in double brackets, you can specify as many sort orders as the various dictionaries enclosed in your structure will be required.

GitHub Project: https://github.com/laowantong/customsort

0
source

All Articles