Reordering dicts list arbitrarily in python

I have a list of 4 dicts (always 4) that look something like this:

[{'id':'1','name':'alfa'},{'id':'2','name':'bravo'},{'id':'3','name':'charlie'},{'id':'4','name':'delta'}] 

I know for sure in what order I want them:

 2, 3, 1, 4 

what's the easiest way to reorder them?

+4
source share
5 answers

If it's always four, and you always know the order, just like that:

 lst = [{...},{...},{...},{...}] ordered = [lst[1],lst[2],lst[0],lst[3]] 

If you wanted to sort them by 'id', in that order:

 ordered = sorted(lst, key=lambda d: [2,3,1,4].index(int(d['id']))) 

Note that index() is O(n) , but does not require the creation of a dictionary. Therefore, for small entrances this can be faster. In your case, there are four elements, ten comparisons are guaranteed. Using timeit , this snippet works 10% faster than a solution based on the tokland dictionary ... but that doesn't really matter, since none of them will be significant.

+4
source

Here's a pretty general function for overlaying the wanted order (any key value that is not in the desired order is placed at the end of the resulting list in an arbitrary sub-order):

 def ordered(somelist, wantedorder, keyfunction): orderdict = dict((y, x) for x, y in enumerate(wantedorder)) later = len(orderdict) def key(item): return orderdict.get(keyfunction(item), later) return sorted(somelist, key=key) 

You will use it as

 import operator sortedlist = ordered(dictlist, ('2', '3', '1', '4'), operator.itemgetter('id')) 
+3
source
 the_list.sort(key=lambda x: (3, 1, 2, 4)[int(x["id"])-1]) 

Update0

New much simpler answer

 the_list = [the_list[i - 1] for i in (2, 3, 1, 4)] 

Thus, the OP can see its desired order, and there is no stupidity when sorting, which is not required here. This is probably fast too.

+2
source

Not a generalized solution:

 lst = [{'id':'1','name':'alfa'},{'id':'2','name':'bravo'},{'id':'3','name':'charlie'},{'id':'4','name':'delta'}] order = ["2", "3", "1", "4"] indexes = dict((idfield, index) for (index, idfield) in enumerate(order)) print sorted(lst, key=lambda d: indexes[d["id"]]) # [{'id': '2', 'name': 'bravo'}, {'id': '3', 'name': 'charlie'}, {'id': '1', 'name': 'alfa'}, {'id': '4', 'name': 'delta'}] 

And here are summarized:

 def my_ordered(it, wanted_order, key): indexes = dict((value, index) for (index, value) in enumerate(wanted_order)) return sorted(it, key=lambda x: indexes[key(x)]) import operator print my_ordered(lst, order, operator.itemgetter("id")) 
+2
source

If you want to reorder without regard to the content of dicts:

 >>> order = 2, 3, 1, 4 >>> d = [{'id':'1','name':'alfa'},{'id':'2','name':'bravo'},{'id':'3','name':'charlie'},{'id':'4','name':'delta'}] >>> index = dict(enumerate(dd)) >>> [index[i-1] for i in order] [{'id': '2', 'name': 'bravo'}, {'id': '3', 'name': 'charlie'}, {'id': '1', 'name': 'alfa'}, {'id': '4', 'name': 'delta'}] 

If you want to create your own sort by 'id' dicts:

 >>> sorted(d, key=lambda x: order.index(int(x['id']))) [{'id': '2', 'name': 'bravo'}, {'id': '3', 'name': 'charlie'}, {'id': '1', 'name': 'alfa'}, {'id': '4', 'name': 'delta'}] 
0
source

Source: https://habr.com/ru/post/1316445/


All Articles