-1
L = [{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':3}]

I want to add quantity base on id ,

So for the list above I would like the output to be:

 [{'id':1,'quantity':4},{'id':2,'quantity':2}]

another example:

L = [{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':2}, {'id':1, 'quantity':3}]

So for the list above I would like the output to be:

 [{'id':1, 'quantity':6}, {'id':2, 'quantity':2}]
Ma0
  • 15,057
  • 4
  • 35
  • 65
zhang olve
  • 89
  • 1
  • 10

4 Answers4

2

In python "group by" functionality may be achieved by itertools.groupby() function:

import itertools

l = [{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':3}]
result = [ {'id': k, 'quantity': sum(_['quantity'] for _ in g)} 
            for k,g in itertools.groupby(sorted(l, key=lambda x:x['id']), key=lambda x:x['id'])]

print(result)

The output:

[{'id': 1, 'quantity': 4}, {'id': 2, 'quantity': 2}]
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • but you are traversing the list once for every unique `id` like that, right? That's quite inefficient. – Ma0 Nov 02 '17 at 08:51
2

This should do what you want:

from collections import defaultdict

def combine(items):
    counts = defaultdict(int)
    for d in items:
        counts[d["id"]] += d["quantity"]

    return [{"id": id, "quantity": q} for id, q in counts.items()]

Examples:

>>> combine([{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':3}])
[{'quantity': 4, 'id': 1}, {'quantity': 2, 'id': 2}]

>>> combine([{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':2}, {'id':1, 'quantity':3}])
[{'quantity': 6, 'id': 1}, {'quantity': 2, 'id': 2}]

This is about as simple and efficient as you're going to get.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
1

convert it to dataframe and then back to dict

import pandas as pd
L = [{'id':1, 'quantity':1}, {'id':2, 'quantity':2}, {'id':1, 'quantity':3}]
output=pd.DataFrame(L).groupby('id')['quantity'].sum().to_dict()
Binyamin Even
  • 3,318
  • 1
  • 18
  • 45
0

Assuming the input is properly defined, here I implemented in a intuitive way to achieve this:

output = {}
keys=[]
for e in L:
    if e['id'] not in keys:
        keys.append(e['id'])
        output[e['id']] = e['quantity']
    else:
        output[e['id']] += e['quantity']

[{'id':key,'identity':values} for key,values in  output.items()]

I was actually wondering that is there any further requirements, for instance, that you need a probably higher efficiency to perform a huge volume of data? If yes, this method seems to be tedious.

Shawn. L
  • 403
  • 1
  • 3
  • 13