我想按“pos”键对字典列表进行排序。但是,如果字典中缺少“pos”,我想保持项目的顺序并假设“pos”是列表中项目的从 1 开始的索引。
这工作正常,只要所有列表项都不同:
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)
输出:
[{'id': '1'}, {'id': '2'}, {'id': '3'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '4'}, {'id': 'ZZZ'}, {'id': 'AAA'}]
但是如果我有多个相同的项目,它就会失败,因为那时
list.index
将返回第一次出现,而不是“假定位置”。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)
实际输出:
[{'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': 'AAA'}]
预期输出:
[{'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '1'}, {'id': '1'}, {'id': 'AAA'}]
如何更改排序以返回预期的输出?
注意:项目 ID 不保证按任何顺序排列,即
1,2,3,4,AAA,ABC,XYZ
是随意选择的。
最佳答案
使用 enumerate :
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},
]
result = [e for _, e in sorted(enumerate(L, 1), key=lambda x: x[1].get("pos", x[0]))]
print(result)
输出
[{'id': '1'}, {'id': '2'}, {'id': '3'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '4'}, {'id': 'ZZZ'}, {'id': 'AAA'}]
对于重复示例:
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},
]
result = [e for _, e in sorted(enumerate(L, 1), key=lambda x: x[1].get("pos", x[0]))]
print(result)
输出
[{'id': '1'}, {'id': '1'}, {'id': '1'}, {'id': 'XYZ', 'pos': 3.1}, {'id': 'ABC', 'pos': 3.2}, {'id': '1'}, {'id': '1'}, {'id': 'AAA'}]
一个可能更清洁的替代方法是使用 itertools.count :
from itertools import count
counter = count(1)
result = sorted(L, key=lambda x: x.get("pos", next(counter)))
print(result)
关于python - 按键对 dict 列表进行排序。如果缺少键,则假定为连续编号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58301650/