4 ms·
I'm not a pythonista, but I'd turn it into a dictionary where the value of `thing` becomes the key, and in the value we sum all those counts. Then turn it back
by mcv 5y ago
I'm not a pythonista, but I'd turn it into a dictionary where the value of `thing` becomes the key, and in the value we sum all those counts. Then turn it back into an array again. That's O(n).
In javascript:
const mylist = [
{'thing': 'A', 'count': 4},
{'thing': 'B', 'count': 2},
{'thing': 'A', 'count': 6}];
const dict = mylist.reduce(({thing, count}, dict) => ({
[thing] : dict[thing] ? dict[thing]+count : count
}, {});
const newList = Object.keys(dict).map(thing => { thing, count: dict[thing] });
(Not tested or anything, so no guarantee that this works right off the bat, but something like this should work.)
- thr0waway164021 5y agoSame algorithm in Python from functools import reduce result = [ {'thing': k, 'count': v} for k, v in reduce( lambda result, item: { **result, item['thing']: item['count'] + result.get(item['thing'], 0) }, mylist, {} ).items() ]
- DangitBobby 5y agoSomething a bit more beginner friendly: agg = {} for item in mylist: if item['thing'] in agg: agg[item['thing']] += item['count'] else: agg[item['thing']] = item['count'] result_list = [] for key, value in agg.items(): result_list.append(dict(thing=key, count=value)) In beginner land, reduce makes your eyes glaze over and dict.get(key, default) is understandable in principle but still confusing in practice.
- Izkata 5y agoAfter almost a decade doing python, I'd probably use a plain loop like this but with ".get(key, default)"
- mcv 5y agoWith the recent changes in Javascript, I've developed an aversion to old fashioned for-loops. I prefer to .map.reduce.filter and if absolutely necessary, .forEach my way through the problem.
- rbanffy 5y agoOn a code review, I'd say I'm impressed, but still demand it written in a way that doesn't require the mindbending this one asks for. We should write code that’s as naïve as possible.