Blabber Blabber - 1 year ago 95
Python Question

Python list of dictionaries containing lists comprehension

I have a list of dictionary containing lists:

a = [{'alpha':'a','val':10,'num':['one','two']},{'alpha':'b','val':22,'num':['two']},{'alpha':'c','val':1,'num':['seven']},{'alpha':'a','val':10,'num':['three','nine']},{'alpha':'b','val':9,'num':['two','four']}]

The output I want is:

[{'alpha':'a','TotalVal':20, num:['one,'two','three','nine'],'numlen':4}, {'alpha':'b','TotalVal':31, num:['two','four'],'numlen':2},{'alpha':'c','val':1,'num':['seven'],'numlen':1}]

I have tried the following:

sumVal = collections.defaultdict(float)
for info in a:
sumVal[info['alpha']] += info['val']

sumVal = [{'alpha': c, 'TotalVal': sumVal[c]} for c in sumVal]

numList = collections.defaultdict(list)
for info in a:
numList = [{'alpha': k, 'num': set(v),'len': len(set(v))} for k,v in numList.items()]

def merge_lists(l1, l2, key):
merged = {}
for item in l1+l2:
if item[key] in merged:
merged[item[key]] = item
return [val for (_, val) in merged.items()]

final = merge_lists(sumVal,numList, 'alpha')

I do not get the desired output for numList. Get the following error.

TypeError: unhashable type: 'list'

How can I get the desired output in lesser number of steps and get rid of the error? Please help!

Answer Source

Not as short as other answers but simple in its implementation

a = [{'alpha':'a','val':10,'num':['one','two']},

new_list = []

# Loop through entries
for entry in a:
    # Store first entries
    if entry['alpha'] not in [i['alpha'] for i in new_list]:
        new_dict = {'alpha': entry['alpha'],
                    'TotalVal': entry['val'],
                    'num': entry['num'],
                    'numlen': len(entry['num'])}

    # Add in additional entries
    for i, n in enumerate(new_list):
        if n['alpha'] == entry['alpha']:
            entry_vals = entry.values()
            new_list[i]['TotalVal'] = new_list[i]['TotalVal'] + entry['val']
            new_list[i]['num'] = new_list[i]['num'] + entry['num']
            new_list[i]['numlen'] = len(new_list[i]['num'])

# filter final data
for i, n in enumerate(new_list):
    # Remove duplicate entries in num
    for entry in n['num']:
        if n['num'].count(entry) > 1:

    # Update numlen
    new_list[i]['numlen'] = len(new_list[i]['num'])

print new_list
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download