Alright. This may be difficult but I have been struggling for quite a bit without great improvement, so I’d like to know what you guys think.
Suppose I have the following list of objects:
objects = [
{'id': '1', 'w': 0.20},
{'id': '1.1', 'w': 0.80},
{'id': '1.2', 'w': 0.20},
{'id': '1.3', 'w': 0.30},
{'id': '1.1.1', 'w': 0.60},
{'id': '1.1.2', 'w': 0.70},
{'id': '1.1.3', 'w': 0.40},
{'id': '1.2.1', 'w': 0.30},
]
I want to sort this list by ‘id’ (e.g. '1', '1.1', '1.1.1', '1.1.2', '1.1.3', '1.2', '1.2.1', '1.3') but then all the elements with the same parent need to be ordered by ‘w’ (in reverse). What do I mean by ‘same parent’?. Well, ‘1’ is parent of ‘1.1’, ‘1.2’ and ‘1.3’. Likewise, ‘1.1’ is parent of ‘1.1.1’, ‘1.1.2’, ‘1.1.3’ and ‘1.2’ is parent of ‘1.2.1’. To illustrate this better, imagine this is a representation of a thread with nested comments (‘1’ is the original post, ‘1.1’ is its answer, and so on).
For now, I have been able to reach the following form:
[ [ {'w': 0.2, 'id': '1'} ], [ {'w': 0.8, 'id': '1.1'}, {'w': 0.3, 'id': '1.3'},
{'w': 0.2, 'id': '1.2'} ], [ {'w': 0.7, 'id': '1.1.2'}, {'w': 0.6, 'id': '1.1.1'},
{'w': 0.4, 'id': '1.1.3'} ], [ {'w': 0.3, 'id': '1.2.1'} ] ]
As you can see, each nested list comprises elements which are children of other element. For example, the second nested list [ {'w': 0.8, 'id': '1.1'}, {'w': 0.3, 'id': '1.3'}, {'w': 0.2, 'id': '1.2'} ] contains all the children of the element [ {'w': 0.2, 'id': '1'} ]. Additionally, each nested list is ordered by ‘w’.
The final result should be something like this (assuming chaining all the inner lists – list(itertools.chain(*b))):
{'id': '1', 'w': 0.20}, {'id': '1.1', 'w': 0.80}, {'id': '1.1.2', 'w': 0.70},
{'id': '1.1.1', 'w': 0.60}, {'id': '1.1.3', 'w': 0.40}, {'id': '1.3', 'w': 0.30},
{'id': '1.2', 'w': 0.20}, {'id': '1.2.1', 'w': 0.30}
Basically, first goes the parent, then its children (ordered by ‘w’), and the same applies to each element (if it has children, of course – here {'id': '1.3', 'w': 0.30} doesn’t have children so we don’t need to do anything with it).
I have tried a few things (too convoluted to be worthy of explanation). I ended up with quite a few conditionals and an ugly code.
How can I accomplish this sorting?.
Thanks in advance.
A simple sort will not solve your problem, because it is not possible to compare any two elements and immediately know when one comes before another (the weight of the parents may change the ordering).
You need to process the list into a tree structure and then extract it in order: