Python元组列表:每个元组的第二个值,仅当元组的第一个val ==某事时

时间:2013-03-30 18:55:26

标签: python list set tuples

我有一个“已标记”元组的列表...其中每个元组都是(tag_id,value)......就像这样:

my_list = [(tag_A, 100), (tag_A, 200), (tag_A, 300), (tag_A, 400), (tag_B, 400), (tag_B, 600)]

我想用相同的标签对每个元组的值求和......以便:

sum_of_all_values_with_tag_A() = 1000

sum_of_all_values_with_tag_B() = 1000

我无法想出一个简单的Pythonic方法。

sum(set(value for tag_id, value in my_list)) 

...返回所有值的总和。

我想我可以使用for或while循环来包装它,这样只有那个带有我想要求和的标签的元组被这个表达式触及......?我需要将与两个标签相关联的值相加...得到两个不同的总数,如上所述区分。但是对于这样的事情来说,不能完全理解这种语法。

这发生在预先存在的功能内部。没有嵌套功能就可以做到这一点。

任何建议都表示赞赏!

4 个答案:

答案 0 :(得分:9)

使用生成器表达式对每个标记求和:

sum(val for tag, val in my_list if tag == tag_A)

您可以在代码上排序,然后使用itertools.groupby创建每个标记组和总和:

from itertools import groupby
from operator import itemgetter

key = itemgetter(0)  # tag
sums = {tag: sum(tup[1] for tup in group)
        for tag, group in groupby(sorted(my_list, key=key), key=key)}

这将产生一个字典映射标签到每个标签总和:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> tag_A, tag_B = 'A', 'B'
>>> my_list = [(tag_A, 100), (tag_A, 200), (tag_A, 300), (tag_A, 400), (tag_B, 400), (tag_B, 600)]
>>> key = itemgetter(0)  # tag
>>> sums = {tag: sum(tup[1] for tup in group)
...         for tag, group in groupby(sorted(my_list, key=key), key=key)}
>>> print sums
{'A': 1000, 'B': 1000}

答案 1 :(得分:6)

方法

将您的数据放入defaultdict(list)。总结一下。

代码

from collections import defaultdict
my_list = [('tag_A', 100), ('tag_A', 200), ('tag_A', 300), ('tag_A', 400), ('tag_B', 400), ('tag_B', 600)]

d = defaultdict(list)
for tag, num in my_list:
    d[tag].append(num)

测试

>>> from collections import defaultdict
>>> my_list = [('tag_A', 100), ('tag_A', 200), ('tag_A', 300), ('tag_A', 400), ('tag_B', 400), ('tag_B', 600)]
>>> 
>>> d = defaultdict(list)
>>> for tag, num in my_list:
...     d[tag].append(num)
... 
>>> from pprint import pprint
>>> pprint(dict(d))
{'tag_A': [100, 200, 300, 400], 'tag_B': [400, 600]}
>>> 
>>> pprint({k: sum(v) for k, v in d.iteritems()})
{'tag_A': 1000, 'tag_B': 1000}

备选摘要例程

def summarize_by_tag(d):
    for k, v in d.iteritems():
        print k, sum(v)

>>> summarize_by_tag(d)
tag_A 1000
tag_B 1000

答案 2 :(得分:3)

与其他答案一样,我只会使用defaultdict,但除非您稍后再次需要这些组。只要在分组时加以总结即可。 my_list可能是一个非常大的迭代,你不会将整个东西存储在内存中。

from collections import defaultdict
my_list = [('tag_A', 100), ('tag_A', 200), ('tag_A', 300), ('tag_A', 400), ('tag_B', 400), ('tag_B', 600)]
result = defaultdict(int)
for tag, value in my_list:
    result[tag] += value
print result

defaultdict(<type 'int'>, {'tag_A': 1000, 'tag_B': 1000})

答案 3 :(得分:1)

没有导入任何东西。

mysum={}
my_list = [('tag_A', 100), ('tag_A', 200), ('tag_A', 300), ('tag_A', 400), ('tag_B', 400), ('tag_B', 600)]
for x in my_list:
    mysum.setdefault(x[0],0)
    mysum[x[0]]+=x[1]
print mysum

输出:

{'tag_A': 1000, 'tag_B': 1000}