如何对对象数组进行分组并在输出中保留其他键

How to group array of objects and keep other keys in output

我有以下合集:

array = [
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val2', 'another_key': 'd'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val1', 'another_key': 'a'},
]

我想按 key1 对象计数进行分组。 对于上面的示例,我想获得下一个选项之一:

[
  {'val1': 3, 'another_key': 'a'},
  {'val3': 2, 'another_key': 'c'},
  {'val2': 1, 'another_key': 'd'},
]

[
  {'key':'val1', count: 3, 'another_key': 'a'},
  {'key':'val3', count: 2, 'another_key': 'c'},
  {'key':'val2', count: 1, 'another_key': 'd'},
]

我想使用 Counter 模块。

我的代码:

from collections import Counter 

groups = Counter([a['key'] for a in array])
groups = groups.most_common()

但我只得到第一把钥匙...

>>> groups
[('val1', 3), ('val3', 2), ('val2', 1)]

我怎样才能同时获得上述格式之一的另一个密钥?

counter = Counter([tuple(a.items()) for a in array])
print(counter)
for tup, count in counter.items():
    print('-----')
    print(tup)
    print(tup[0][1])
    d = dict(tup)
    print(d)
    print(d['another_key'])
    print(count)

结果:

Counter({(('another_key', 'a'), ('key', 'val1')): 3, (('another_key', 'c'), ('key', 'val3')): 2, (('another_key', 'd'), ('key', 'val2')): 1})
-----
(('another_key', 'c'), ('key', 'val3'))
c
{'another_key': 'c', 'key': 'val3'}
c
2
-----
(('another_key', 'a'), ('key', 'val1'))
a
{'another_key': 'a', 'key': 'val1'}
a
3
-----
(('another_key', 'd'), ('key', 'val2'))
d
{'another_key': 'd', 'key': 'val2'}
d
1

再补充一点你的理解:

groups = Counter(a[key] for a in array for key in a)

它可以是生成器表达式而不是列表理解。

由于没有答案为您提供您要求的输出格式,因此您是:

counter = Counter((item['key'], item['another_key']) for item in array)
groups = [{t[0]: count, 'another_key': t[1]} for t, count in counter.most_common()]

此解决方案为您提供了您建议的第一种答案格式。

第二种格式可以通过更改第二行获得:

groups = [{'count': count, 'key': t[0], 'another_key': t[1]} for t, count in counter.most_common()]

由于稍后发布,如果不需要排序,counter.most_common()可以换成counter.items()

只需将要保留的键放入可散列的集合中即可;元组非常适合这个。然后,您可以通过迭代元组和计数器中的关联计数轻松构建新的字典。

from collections import Counter
from pprint import pprint

arr = [
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val1', 'another_key': 'a'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val2', 'another_key': 'd'},
  {'key': 'val3', 'another_key': 'c'},
  {'key': 'val1', 'another_key': 'a'},
]

groups = Counter((d['key'], d['another_key']) for d in arr)

new_arr = [{'key': t[0], 'another_key': t[1], 'count': val} 
    for t, val in groups.items()]

pprint(new_arr)

输出

[{'another_key': 'd', 'count': 1, 'key': 'val2'},
 {'another_key': 'a', 'count': 3, 'key': 'val1'},
 {'another_key': 'c', 'count': 2, 'key': 'val3'}]

如果您希望列表按计数降序排列,则可以使用 Counter.most_common 方法:

ordered = [{'key': t[0], 'another_key': t[1], 'count': val} 
    for t, val in groups.most_common()]
pprint(ordered)    

输出

[{'another_key': 'a', 'count': 3, 'key': 'val1'},
 {'another_key': 'c', 'count': 2, 'key': 'val3'},
 {'another_key': 'd', 'count': 1, 'key': 'val2'}]