5

I have a python list like this:

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

I am trying to write the code to join the dictionaries with the same name by also adding the quantities. The final list will be that:

user = [
        {'name': 'ozzy', 'quantity': 8},
        {'name': 'frank', 'quantity': 6},
        {'name': 'james', 'quantity': 7}
        ]

I have tried a few things but I am struggling to get the right code. The code I have written below is somewhat adding the values (actually my list is much longer, I have just added a small portion for reference).

newList = []
    quan = 0
    for i in range(0,len(user)):      
        originator = user[i]['name']
        for j in range(i+1,len(user)):
            if originator == user[j]['name']:
                quan = user[i]['quantity'] + user[j]['quantity']
                newList.append({'name': originator, 'Quantity': quan})

can you please help me to get the correct code?

Rikkas
  • 572
  • 4
  • 19

5 Answers5

5

Just count the items in a collections.Counter, and expand back to list of dicts if needed:

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

import collections

d = collections.Counter()
for u in user:
    d[u['name']] += u['quantity']

print(dict(d))

newlist = [{'name' : k, 'quantity' : v} for k,v in d.items()]

print(newlist)

outputs Counter dict first, which is already sufficient:

{'frank': 6, 'ozzy': 8, 'james': 7}

and the reformatted output using list of dicts:

[{'name': 'frank', 'quantity': 6}, {'name': 'ozzy', 'quantity': 8}, {'name': 'james', 'quantity': 7}]
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

The solution is also straightforward with a standard dictionary. No need for Counter or OrderedDict here:

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

dic = {}
for item in user:
  n, q = item.values()
  dic[n] = dic.get(n,0) + q
print(dic)

user = [{'name':n, 'quantity':q} for n,q in dic.items()]
print(user)

Result:

{'ozzy': 8, 'frank': 6, 'james': 7}
[{'name': 'ozzy', 'quantity': 8}, {'name': 'frank', 'quantity': 6}, {'name': 'james', 'quantity': 7}]
sciroccorics
  • 2,357
  • 1
  • 8
  • 21
  • Thanks, this is working good but when I have a key with a blank like 'name surname' then I can not use it withing dict() but instead {'name surname' : k, 'quantity' : v} fixed that part. – Rikkas Apr 18 '18 at 11:24
  • Good point! As your example didn't show that case, I skipped it. I've edited the answer... – sciroccorics Apr 18 '18 at 11:26
0

I would suggest changing the way the output dictionary looks so that it is actually useable. Consider something like this

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

data = {}
for i in user:
    print(i)
    if i['name'] in data:
        data[i['name']] += i['quantity']
    else:
        data.update({i['name']: i['quantity']})

print(data)

{'frank': 6, 'james': 7, 'ozzy': 8}

JahKnows
  • 2,618
  • 3
  • 22
  • 37
  • everything in your for loop could be condensed down to a single line using `.get()` - `data[i['name']] = data.get(i['name'], 0) + i['quantity']` - but this still doesn't give OP's desired output – asongtoruin Apr 18 '18 at 09:31
0

If you need to maintain the original relative order:

from collections import OrderedDict

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

d = OrderedDict()
for item in user:
    d[item['name']] = d.get(item['name'], 0) + item['quantity']

newlist = [{'name' : k, 'quantity' : v} for k, v in d.items()]
print(newlist)

Output:

[{'name': 'ozzy', 'quantity': 8}, {'name': 'frank', 'quantity': 6}, {'name': 'james', 'quantity': 7}]
jdehesa
  • 58,456
  • 7
  • 77
  • 121
0
user = [
    {'name': 'ozzy', 'quantity': 8},
    {'name': 'frank', 'quantity': 6},
    {'name': 'james', 'quantity': 7}
]

reference_dict = {}

for item in user :
    reference_dict[item['name']] = reference_dict.get(item['name'],0) + item['quantity']

#Creating new list from reference dict
updated_user = [{'name' : k , 'quantity' : v} for k,v in reference_dict.items()]

print updated_user