Reordering List Of Dicts Arbitrarily In Python
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"