2

「タグ付き」タプルのリストがあります...各タプルは(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ループでラップできると思います...?両方のタグに関連付けられた値を合計する必要があります...上記のように区別された 2 つの異なる合計が得られます。しかし、そのようなことのエレガントな構文を完全に理解することはできません。

これは、既存の関数内で発生しています。関数をネストせずにそれを行うのは素晴らしいことです。

どんな提案でも大歓迎です!

4

4 に答える 4

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}
于 2013-03-30T18:56:35.150 に答える
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
于 2013-03-30T19:14:21.343 に答える
3

他の回答と同様に、defaultdict後でグループが必要にならない限り、私はただ使用します。グループとしてそれらを合計するだけです。my_list は非常に大きな iterable になる可能性があり、すべてをメモリに保存していません。

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})
于 2013-03-31T00:00:16.993 に答える