Skip to content Skip to sidebar Skip to footer

Reordering List Of Dicts 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 kno

Solution 1:

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

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

If you meant 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 doesn't require you to build a dictionary. So for small inputs, this may actually be faster. In your case, there are four elements, ten comparisons are guaranteed. Using timeit, this snippet runs 10% faster than the dictionary based solution by tokland... but it doesn't really matter since neither will likely be significant.

Solution 2:

Here's a pretty general function to impose a wanted order (any key value not in the wanted order is placed at the end of the resulting list, in arbitrary sub-order):

defordered(somelist, wantedorder, keyfunction):
    orderdict = dict((y, x) for x, y inenumerate(wantedorder))
    later = len(orderdict)
    defkey(item):
        return orderdict.get(keyfunction(item), later)
    returnsorted(somelist, key=key)

You'd be using it as

importoperator
sortedlist = ordered(dictlist, ('2', '3', '1', '4'),
                     operator.itemgetter('id'))

Solution 3:

A non-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) inenumerate(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 generalized:

defmy_ordered(it, wanted_order, key):
    indexes = dict((value, index) for (index, value) inenumerate(wanted_order))
    returnsorted(it, key=lambda x: indexes[key(x)])

import operator  
print my_ordered(lst, order, operator.itemgetter("id"))

Solution 4:

the_list.sort(key=lambda x: (3, 1, 2, 4)[int(x["id"])-1])

Update0

A new much simpler answer

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

This way the OP can see his desired ordering, and there's no silliness with sorting, which is not required here. It's probably fast too.

Solution 5:

If you want to re-order without regard for content of the 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 base your sorting on the 'id' of the 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'}]

Post a Comment for "Reordering List Of Dicts Arbitrarily In Python"