What is be best way to reduce this series of tuples
('x', 0.29, 'a')
('x', 0.04, 'a')
('x', 0.03, 'b')
('x', 0.02, 'b')
('x', 0.01, 'b')
('x', 0.20, 'c')
('x', 0.20, 'c')
('x', 0.10, 'c')
into:
('x', 0.29 * 0.04 , 'a')
('x', 0.03 * 0.02 * 0.01, 'b')
('x', 0.20 * 0.20 * 0.10, 'c')
EDIT:
X is a constant, it is known in advance and can be safely ignored
And the data can be treated as pre-sorted on the third element as it appears above.
I am trying to do it at the moment using operator.mul, and a lot of pattern matching, and the odd lambda function... but I'm sure there must be an easier way!
Can I just say thank you for ALL of the answers. Each one of them was fantastic, and more than I could have hoped for. All I can do is give them all an upvote and say thanks!
Here's a functional programming approach:
from itertools import imap, groupby
from operator import itemgetter, mul
def combine(a):
for (first, last), it in groupby(a, itemgetter(0, 2)):
yield first, reduce(mul, imap(itemgetter(1), it), 1.0), last
Here's a more stateful approach. (I like @Sven's better.)
def combine(a)
grouped = defaultdict(lambda: 1)
for _, value, key in a:
grouped[key] *= value
for key, value in grouped.items():
yield ('x', value, key)
This is less efficient if the data are already sorted, since it keeps more in memory than it needs to. Then again, that probably won't matter, because it's not stupidly inefficient either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With