繁体   English   中英

如何通过多个键对数组进行分组?

[英]How to group an array by multiple keys?

我想要一个函数,该函数可以将字典列表分组为字典的子列表,具体取决于所有字典共有的任意键集。

例如,我希望根据一组特定的键将以下列表分组为词典的子列表

l = [{'name':'b','type':'new','color':'blue','amount':100},{'name':'c','type':'new','color':'red','amount':100},{'name':'d','type':'old','color':'gold','amount':100},{'name':'e','type':'old','color':'red','amount':100},
{'name':'f','type':'old','color':'red','amount':100},{'name':'g','type':'normal','color':'red','amount':100}]

如果我想按类型分组,将得到以下列表,其中包含一个子列表,其中每个子列表具有相同的类型:

[[{'name':'b','type':'new','color':'blue','amount':100},{'name':'c','type':'new','color':'red','amount':100}],[{'name':'d','type':'old','color':'gold','amount':100},{'name':'e','type':'old','color':'red','amount':100},
{'name':'f','type':'old','color':'red','amount':100}],[{'name':'g','type':'normal','color':'red','amount':100}]]

如果要按类型和颜色分组,则在列表包含具有相同类型和颜色的子列表的情况下,将导致以下结果:

[[{'name':'b','type':'new','color':'blue','amount':100}],[{'name':'c','type':'new','color':'red','amount':100}],[{'name':'d','type':'old','color':'gold','amount':100}],[{'name':'e','type':'old','color':'red','amount':100},
{'name':'f','type':'old','color':'red','amount':100}],[{'name':'g','type':'normal','color':'red','amount':100}]]

我了解以下功能可以按一个键进行分组,但是我想按多个键进行分组:

 def group_by_key(l,i):

      l = [list(grp) for key, grp in itertools.groupby(sorted(l, key=operator.itemgetter(i)), key=operator.itemgetter(i))]

这是我使用上面的group_by_function的尝试

 def group_by_multiple_keys(l,*keys):
      for key in keys:
          l = group_by_key(l,key)
          l = [item for sublist in l for item in sublist]
      return l 

那里的问题是,它在按键对它进行分组后立即对其进行了取消分组。 相反,我想通过另一个键将其重新分组,并且仍然具有一个子列表列表。

itertools.groupby() + operator.itemgetter()将做您想要的。 groupby()接受一个可迭代的键函数,并通过将每个项目传递给键函数所返回的值将可迭代的项分组。 itemgetter()是一个返回函数的工厂,该函数从传递给它的任何项目中获取指定的项目。

from __future__ import print_function

import pprint

from itertools import groupby
from operator import itemgetter


def group_by_keys(iterable, keys):
    key_func = itemgetter(*keys)

    # For groupby() to do what we want, the iterable needs to be sorted
    # by the same key function that we're grouping by.
    sorted_iterable = sorted(iterable, key=key_func)

    return [list(group) for key, group in groupby(sorted_iterable, key_func)]


dicts = [
    {'name': 'b', 'type': 'new', 'color': 'blue', 'amount': 100},
    {'name': 'c', 'type': 'new', 'color': 'red', 'amount': 100},
    {'name': 'd', 'type': 'old', 'color': 'gold', 'amount': 100},
    {'name': 'e', 'type': 'old', 'color': 'red', 'amount': 100},
    {'name': 'f', 'type': 'old', 'color': 'red', 'amount': 100},
    {'name': 'g', 'type': 'normal', 'color': 'red', 'amount': 100}
    ]

例子:

>>> pprint.pprint(group_by_keys(dicts, ('type',)))
[[{'amount': 100, 'color': 'blue', 'name': 'b', 'type': 'new'},
  {'amount': 100, 'color': 'red', 'name': 'c', 'type': 'new'}],
 [{'amount': 100, 'color': 'gold', 'name': 'd', 'type': 'old'},
  {'amount': 100, 'color': 'red', 'name': 'e', 'type': 'old'},
  {'amount': 100, 'color': 'red', 'name': 'f', 'type': 'old'}],
 [{'amount': 100, 'color': 'red', 'name': 'g', 'type': 'normal'}]]
>>> 
>>> pprint.pprint(group_by_keys(dicts, ('type', 'color')))
[[{'amount': 100, 'color': 'blue', 'name': 'b', 'type': 'new'}],
 [{'amount': 100, 'color': 'red', 'name': 'c', 'type': 'new'}],
 [{'amount': 100, 'color': 'gold', 'name': 'd', 'type': 'old'}],
 [{'amount': 100, 'color': 'red', 'name': 'e', 'type': 'old'},
  {'amount': 100, 'color': 'red', 'name': 'f', 'type': 'old'}],
 [{'amount': 100, 'color': 'red', 'name': 'g', 'type': 'normal'}]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM