Skip to content Skip to sidebar Skip to footer

From A Dictionary With Repeated Values, How To Create A New One Excluding The Repeats And Incrementing A Counter Inside The Dictionary?

Turn this: a = {'1': {'name': 'Blue', 'qty': '1'}, '2': {'name': 'Green', 'qty': '1'}, '3': {'name': 'Blue', 'qty': '1'}, '4': {'name': 'Blue', 'qty': '1'}} into th

Solution 1:

This seems to work:

from collections import defaultdict

result = defaultdict(lambda: 0)

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

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

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

If I could choose data structures, it might look like this:

fromoperator import addfrom 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})

Solution 2:

A cumbersome two-liner:

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))}

Following comments from André and the original poster, here is an even more complicated solution.

First, convert the original dict 'name' and 'sub' keys to a comma-delimited string, so we can use set():

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

This returns

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

Then use the nested dict and list comprehensions as below:

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))}

Hope this helps.

Post a Comment for "From A Dictionary With Repeated Values, How To Create A New One Excluding The Repeats And Incrementing A Counter Inside The Dictionary?"