I want so sort a list of dictionaries by the key "pos". However, if "pos" is missing in the dict, I want to keep the order of the item(s) and assume that "pos" is the item's 1-based index in the list.
This is working fine, as long as all list items are different:
L = [
{ "id": "1" }, # assume pos: 1
{ "id": "2" }, # assume pos: 2
{ "id": "3" }, # assume pos: 3
{ "id": "4" }, # assume pos: 4
{ "id": "ZZZ" }, # assume pos: 5
{ "id": "AAA" }, # assume pos: 6
{ "id": "ABC", "pos": 3.2 },
{ "id": "XYZ", "pos": 3.1 },
]
s = sorted(L,key=lambda i:i.get("pos",L.index(i)+1))
print(s)
Output:
[{'id': '1'}, {'id': '2'}, {'id': '3'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '4'}, {'id': 'ZZZ'}, {'id': 'AAA'}]
But it fails if I have multiple of the same items, because then list.index will return the first occurence, rather than the "assumed position".
L = [
{ "id": "1" }, # assume pos: 1
{ "id": "1" }, # assume pos: 2
{ "id": "1" }, # assume pos: 3
{ "id": "1" }, # assume pos: 4
{ "id": "1" }, # assume pos: 5
{ "id": "AAA" }, # assume pos: 6
{ "id": "ABC", "pos": 3.2 },
{ "id": "XYZ", "pos": 3.1 },
]
s = sorted(L,key=lambda i:i.get("pos",L.index(i)+1))
print(s)
Actual output:
[{'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': 'AAA'}]
Expected output:
[{'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '1'}, {'id': '1'}, {'id': 'AAA'}]
How can the sorting be changed to return the expected output?
Note: the item IDs are not guaranteed to be in any order, that means 1,2,3,4,AAA,ABC,XYZ have been chosen arbitrarily.