pattern matching, tuples and multiplication in Python

限于喜欢 提交于 2019-12-06 06:06:50

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.

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

Given that you are ultimately going to multiply together all of the found values, instead of accumulating a list of the values and multiplying them at the end, change your defaultdict to take an initializer method that sets new keys to 1, and then multiply as you go:

data = [('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'),]

from collections import defaultdict

def reduce_by_key(datalist):

    proddict = defaultdict(lambda : 1)
    for _,factor,key in datalist:
        proddict[key] *= factor

    return [('x', val, key) for key,val in sorted(proddict.items())]

print reduce_by_key(data)

Gives:

[('x', 0.011599999999999999, 'a'), 
 ('x', 5.9999999999999993e-06, 'b'), 
 ('x', 0.004000000000000001, 'c')]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!