簡體   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