从具有重复值的字典中,如何创建一个不包括重复值的新字典并增加字典内的计数器?

From a dictionary with repeated values, how to create a new one excluding the repeats and incrementing a counter inside the dictionary?

转这个:

a = {'1': {'name': 'Blue', 'qty': '1'},
     '2': {'name': 'Green', 'qty': '1'},
     '3': {'name': 'Blue', 'qty': '1'},
     '4': {'name': 'Blue', 'qty': '1'}}

进入这个:

b = {'1': {'name': 'Blue', 'qty': '3'},
     '2': {'name': 'Green', 'qty': '1'}}

我能够排除重复值,但无法增加 'qty' 字段。

b = {}

for k,v in a.iteritems():
    if v not in b.values():
        b[k] = v

这似乎有效:

from collections import defaultdict

result = defaultdict(lambda: 0)

# Summarize quantities for each name
for item in a.values():
    result[item['name']] += int(item['qty'])

# Convert to your funny format
b = {str(i+1): v for i, v in enumerate({'name': key, 'qty': str(val)} for key, val in result.items())}

# b contains:
# {'1': {'name': 'Blue', 'qty': '3'}, '2': {'name': 'Green', 'qty': '1'}}

如果我可以选择数据结构,它可能看起来像这样:

from operator import add
from collections import Counter

a = [('Blue', 1), ('Green', 1), ('Blue', 1), ('Blue', 1)]
b = reduce(add, [Counter(**{x[0]: x[1]}) for x in a])
# b contains:
# Counter({'Blue': 3, 'Green': 1})

繁琐的两行:

data = [v['name'] for v in a.values()]

b = {str(i+1): {'name': j, 'qty': data.count(j)} for i, j in enumerate(set(data))}

根据 André 和发帖人的评论,这里有一个更复杂的解决方案。

首先,将原始字典'name''sub'键转换为逗号分隔的字符串,这样我们就可以使用set():

data = [','.join([v['name']]+v['sub']) for v in a.values()]

这个returns

['Blue,sky,ethernet cable', 'Green', 'Blue,sky,ethernet cable', 'Blue,sea']

然后使用嵌套的字典和列表理解如下:

b = {str(i+1): {'name': j.split(',')[0], 'qty': sum([int(qty['qty']) for qty in a.values() if (qty['name']==j.split(',')[0]) and (qty['sub']==j.split(',')[1:])]), 'sub': j.split(',')[1:]} for i, j in enumerate(set(data))}

希望这对您有所帮助。