按缺少某些项的值对字典列表进行排序

2024-10-04 11:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的清单:

a = [
   {'p': 3, 'id': 'ab1'},
   {'p': 10, 'id': 'ab2'},
   {'p': 5, 'id': 'ab3'},
   {'p': 8, 'id': 'ab4'},
   {'id': 'ab5'}
]

我想按a的值对p进行排序。如果dict没有p,就把它放在后面。 我试着这样做:

print sorted(a, key=lambda i: i.get('p'))

结果是:

[{'id': 'ab5'}, {'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}]

但你想得到的是:

[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'},{'id': 'ab5'}]

怎样才能用更简单的方法得到正确的结果?你知道吗


Tags: 方法lambdakeyidget排序dictsorted
3条回答

对于python2和python3两者,您可以如下操作,其中我假设p的值丢失,我假设sys.maxsize的值丢失,这将确保如果p的值丢失,它们总是在列表的末尾

import sys
a = [
   {'p': 3, 'id': 'ab1'},
   {'p': 10, 'id': 'ab2'},
   {'p': 5, 'id': 'ab3'},
   {'p': 8, 'id': 'ab4'},
   {'id': 'ab5'}
]

print(sorted(a, key=lambda i: i.get('p', sys.maxsize)))

这会给你

[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}, {'id': 'ab5'}]

如果与sys.maxsize相比,另一个解决方案是过度杀戮,则将没有键p的字典分离出来,对包含键p的剩余字典排序,然后通过附加非p键字典来扩展它。这也避免了我们为item.get()中的p提供默认值

import sys
a = [
   {'p': 3, 'id': 'ab1'},
   {'p': 10, 'id': 'ab2'},
   {'p': 5, 'id': 'ab3'},
   {'p': 8, 'id': 'ab4'},
   {'id': 'ab5'}
]

#Dictionaries with key p
p_items = [item for item in a if 'p' in item.keys()]

#Dictionaries not with key p
non_p_items = [item for item in a if 'p' not in item.keys()]

#Sort the p-key dictionaries
result = sorted(p_items, key=lambda i: i.get('p'))

#Attach non p-key dictionay items at end
result.extend(non_p_items)

print(result)

这里有一个我不喜欢使用lambda的选项:

import sys
from operator import methodcaller

a = [
   {'p': 3, 'id': 'ab1'},
   {'p': 10, 'id': 'ab2'},
   {'p': 5, 'id': 'ab3'},
   {'p': 8, 'id': 'ab4'},
   {'id': 'ab5'}
]

print(sorted(a, key=methodcaller('get', 'p', sys.maxsize)))

使用

a = [
   {'p': 3, 'id': 'ab1'},
   {'p': 10, 'id': 'ab2'},
   {'p': 5, 'id': 'ab3'},
   {'p': 8, 'id': 'ab4'},
   {'id': 'ab5'}
]

print(sorted(a, key=lambda i: i.get('p', "NA"))) #Setting a string as a default value. 
#python 3   > https://stackoverflow.com/questions/49829732/sorting-a-mixed-list-of-ints-and-strings
print(sorted(a, key=lambda v: (isinstance(v.get('p', "NA"), str), v.get('p', "NA"))))

输出:

[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}, {'id': 'ab5'}]

相关问题 更多 >