对列表中的项目进行分组的 Pythonic 方法

标签 python list dictionary collections

<分区>

考虑一个字典列表:

items = [
    {'a': 1, 'b': 9, 'c': 8},
    {'a': 1, 'b': 5, 'c': 4},
    {'a': 2, 'b': 3, 'c': 1},
    {'a': 2, 'b': 7, 'c': 9},
    {'a': 3, 'b': 8, 'c': 2}
]

是否有一种 pythonic 方法可以通过它们的 a 字段提取和分组这些项目,这样:

result = {
    1 : [{'b': 9, 'c': 8}, {'b': 5, 'c': 4}]
    2 : [{'b': 3, 'c': 1}, {'b': 7, 'c': 9}]
    3 : [{'b': 8, 'c': 2}]
}

对任何类似的 Pythonic 结构的引用表示赞赏。

最佳答案

使用itertools.groupby :

>>> from itertools import groupby
>>> from operator import itemgetter
>>> {k: list(g) for k, g in groupby(items, itemgetter('a'))}
{1: [{'a': 1, 'c': 8, 'b': 9},
     {'a': 1, 'c': 4, 'b': 5}],
 2: [{'a': 2, 'c': 1, 'b': 3},
     {'a': 2, 'c': 9, 'b': 7}],
 3: [{'a': 3, 'c': 2, 'b': 8}]}

如果项目没有按顺序排序,那么您可以对它们进行排序,然后使用 groupby 或者您可以使用 collections.OrderedDict(如果顺序很重要)或 collections.defaultdict 在 O(N) 时间内完成:

>>> from collections import OrderedDict
>>> d = OrderedDict()
>>> for item in items:
...     d.setdefault(item['a'], []).append(item)
...     
>>> dict(d.items())
{1: [{'a': 1, 'c': 8, 'b': 9},
     {'a': 1, 'c': 4, 'b': 5}],
 2: [{'a': 2, 'c': 1, 'b': 3},
     {'a': 2, 'c': 9, 'b': 7}],
 3: [{'a': 3, 'c': 2, 'b': 8}]}

更新:

我看到你只希望返回那些我们没有用于分组的键,为此你需要做这样的事情:

>>> group_keys = {'a'}
>>> {k:[{k:d[k] for k in d.viewkeys() - group_keys} for d in g]
                                   for k, g in groupby(items, itemgetter(*group_keys))}
{1: [{'c': 8, 'b': 9},
     {'c': 4, 'b': 5}],
 2: [{'c': 1, 'b': 3},
     {'c': 9, 'b': 7}],
 3: [{'c': 2, 'b': 8}]}

关于对列表中的项目进行分组的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23339380/

相关文章:

Python for 循环计数器列表 - 计数器不工作

c# - 在 List<Product> 中搜索产品名称

c++ - C++中的哈希表错误

dictionary - 反转 f# Map <'a,Map<' b ,'T>>) -> Map<' b,Map <'a,' T>> 中的嵌套字典

java - 使用 java.util.Map 时出现编译问题

java - 配置 Salt API - Java

python - 使用 tkinter 在 Windows 上使用全局热键

python - 在 Swift 中运行 Python

python - ZeroMQ:每种数据类型的套接字还是只有一个套接字?

python - Jinja 使用 for 列出嵌套 JSON