按dict值对集合列表进行排序,按名称对列表进行分组

时间:2019-12-20 14:51:09

标签: python python-3.x

我试图很好地命名问题标题,但这很复杂。所以,请给我一个例子,会更好。我有这样的东西:

[{'level': 4, 'name': 'Docker'}, {'level': 1, 'name': 'Python'}, {'level': 3, 'name': 'JavaScript'}, {'level': 1, 'name': 'HTML'}]

我希望得到这个:

[{'level': 4, 'name': ['Docker']}, {'level': 3, 'name': ['JavaScript']}, {'level': 1, 'name': ['Python', 'HTML']}]

我用powers.sort(key=lambda x: x['level'], reverse=True)按字典值对列表进行了排序,得到了imo接近解决方案的列表。

[{'level': 4, 'name': 'Docker'}, {'level': 3, 'name': 'JavaScript'}, {'level': 1, 'name': 'Python'}, {'level': 1, 'name': 'HTML'}]

感谢您对names分组level的任何帮助!

3 个答案:

答案 0 :(得分:2)

正如一位评论者所说,您可以使用defaultdict来做到这一点:

from collections import defaultdict

lang_list = [{'level': 4, 'name': 'Docker'}, {'level': 1, 'name': 'Python'}, {'level': 3, 'name': 'JavaScript'}, {'level': 1, 'name': 'HTML'}]

lvl_dict = defaultdict(list)
for d in lang_list:
    lvl_dict[d['level']].append(d['name'])

lvl_list = [{'level': k, 'name': v} for k, v in lvl_dict.items()]

lvl_list.sort(key=lambda x: x['level'], reverse=True)
[{'level': 4, 'name': ['Docker']}, {'level': 3, 'name': ['JavaScript']}, {'level': 1, 'name': ['Python', 'HTML']}]

答案 1 :(得分:1)

那是因为您只进行 排序;分组是另一个显式操作。

>>> from itertools import groupby
>>> from operator import itemgetter
>>> from pprint import pprint
>>> powers = [{'level': 4, 'name': 'Docker'}, {'level': 1, 'name': 'Python'}, {'level': 3, 'name': 'JavaScript'}, {'level': 1, 'name': 'HTML'}]
>>> get_level = itemgetter('level')
>>> get_name = itemgetter('name')
>>> def sort_and_group(lst, getter):
...   return groupby(sorted(lst, key=getter), getter)
...
>>> pprint([dict(level=k, name=list(map(get_name, v))) for k, v in sort_and_group(powers, get_level)])
[{'level': 1, 'name': ['Python', 'HTML']},
 {'level': 3, 'name': ['JavaScript']},
 {'level': 4, 'name': ['Docker']}]

在大多数情况下,每个公共属性都需要一个组,因此在分组之前按同一属性进行排序是很常见的。

答案 2 :(得分:0)

使用熊猫:

import pandas as pd

a = [{'level': 4, 'name': 'Docker'}, {'level': 1, 'name': 'Python'}, {'level': 3, 'name': 'JavaScript'}, {'level': 1, 'name': 'HTML'}]

res = (pd.DataFrame(a).groupby('level')['name']
                      .apply(list).reset_index(name='name')
                      .sort_values('level',ascending=False)
                      .to_dict('records'))