如何在Python中使用Counter和字典列表

问题描述 投票:0回答:4

有了这样的列表,我可以通过以下方式获得相同值的组:

N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
C = Counter(N)
print([[k, ] * v for k, v in C.items()])

得到以下结果。

[[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]

但是如果我有以下列表

N = [{'doc':'A','value':300,'W':1},{'doc':'B','value':301,'W':0.5},{'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3},{'doc':'E','value':300,'W':1},]

我想按照与上一个相同的方式进行分组,使用键“value”对它们进行分组,即:

[[{'doc':A,'value':300,'W':1}, {'doc':'E','value':300,'W':1}],[{'doc':'B','value':301,'W':0.5},{'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3}]]

有人可以帮忙吗?

python list dictionary counter
4个回答
2
投票

您可以使用

collections.defaultdict
来解决这个问题。

collections.Counter
仅对递增整数计数器有用,即便如此,仅适用于可哈希对象。这不是您想要在这里做的事情。

from collections import defaultdict

N = [{'doc':'A','value':300,'W':1}, {'doc':'B','value':301,'W':0.5},
     {'doc':'C','value':301,'W':0.45}, {'doc':'D','value':301,'W':0.3},
     {'doc':'E','value':300,'W':1},]

d = defaultdict(list)

for i in N:
    d[i['value']].append(i)

res = list(d.values())

# [[{'W': 1, 'doc': 'A', 'value': 300}, {'W': 1, 'doc': 'E', 'value': 300}],
#  [{'W': 0.5, 'doc': 'B', 'value': 301},
#   {'W': 0.45, 'doc': 'C', 'value': 301},
#   {'W': 0.3, 'doc': 'D', 'value': 301}]]

顺便说一句,这也为您的第一个问题提供了更直接的解决方案:

N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]

d = defaultdict(list)

for i in N:
    d[i].append(i)

res = list(d.values())

# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

1
投票

由于多种原因,这不能用计数器来完成:

  1. 整数是可散列的,而字典则不然。
    Counter
    仅适用于可哈希值。
  2. 所有分组的整数都相同,但字典不同。只有您分组的字典的“value”键是相同的。即使
    Counter
    与字典一起使用,它也只会每组保留 1 个字典并丢弃其余的。

这里的解决方案是使用

defaultdict
而不是
Counter
:

from collections import defaultdict

N = [{'doc':'A','value':300,'W':1},{'doc':'B','value':301,'W':0.5},
     {'doc':'C','value':301,'W':0.45},{'doc':'D','value':301,'W':0.3},
     {'doc':'E','value':300,'W':1}]

groups = defaultdict(list)
for dic in N:
    groups[dic['value']].append(dic)

result = list(groups.values())
# [[{'W': 1, 'doc': 'A', 'value': 300}, {'W': 1, 'doc': 'E', 'value': 300}],
#  [{'W': 0.5, 'doc': 'B', 'value': 301},
#   {'W': 0.45, 'doc': 'C', 'value': 301},
#   {'W': 0.3, 'doc': 'D', 'value': 301}]]

0
投票

无需任何导入的简单手动方法怎么样:

N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]

d={}

for i,j in enumerate(N):
    if j not in d:
        d[j]=[j]
    else:
        d[j].append(j)

print(d)

输出:

{1: [1], 2: [2, 2], 3: [3, 3, 3], 4: [4, 4, 4, 4], 5: [5, 5, 5, 5, 5]}

或:

print(d.values())

输出:

[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

0
投票

也可以使用 itertools 来完成分组。第一个可以复制为

import itertools

N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]

nn = itertools.groupby(N)

r = []

for i, j in nn:
    r.extend([list(j)])

print(r)

#[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

第二个是字典列表,因此在我们应用 itertools.groupby() 之前必须对其进行排序。

Ndoc = [{'doc':'A','value':300,'W':1}, {'doc':'B','value':301,'W':0.5},
     {'doc':'C','value':301,'W':0.45}, {'doc':'D','value':301,'W':0.3},
     {'doc':'E','value':300,'W':1},]

Ndoc_sorted = sorted(Ndoc,key=lambda x:x['value'])

docs2 = itertools.groupby(Ndoc_sorted, lambda x:x['value'])

dd = {} 

for i,j in docs2:
    dd[i]=list(j)
    
print(dd.values())

#dict_values([[{'doc': 'A', 'value': 300, 'W': 1}, {'doc': 'E', 'value': 300, 'W': 1}], [{'doc': 'B', 'value': 301, 'W': 0.5}, {'doc': 'C', 'value': 301, 'W': 0.45}, {'doc': 'D', 'value': 301, 'W': 0.3}]])
© www.soinside.com 2019 - 2024. All rights reserved.