1

リストがあるとしましょう:

l = [{"num1":3, "num2":8, "num3":5, "type":"A"}, {"num1":2, "num2":5, "num3":5, "type":"B"}, {"num1":5, "num2":2, "num3":1, "type":"A"}, {"num1":4, "num2":4, "num3":9, "type":"B"}

そして私は2つの辞書を作成したい: sumA:

{"num1":8, "num2":10, "num3":6}

合計B:

{"num1":6, "num2":9, "num3":14}

できるだけシンプルで読みやすいものにしたいと思っています。あまりにも多くの変数を使用して恐ろしい方法でそれを行うことができました...

ありがとう!

4

3 に答える 3

1

これは、いくつかのlist および dict 内包表記を使用してかなり簡単に実行できます。

from operator import itemgetter
from itertools import groupby

l = [{"num1": 3, "num2": 8, "num3": 5, "type": "A"},
     {"num1": 2, "num2": 5, "num3": 5, "type": "B"},
     {"num1": 5, "num2": 2, "num3": 1, "type": "A"},
     {"num1": 4, "num2": 4, "num3": 9, "type": "B"}]

wanted_values = {"num1", "num2", "num3"}

type_getter = itemgetter("type")
groups = [(group, list(items)) for group, items in 
          groupby(sorted(l, key=type_getter), type_getter)]

print({group: {k: sum(map(itemgetter(k), items)) for k in wanted_values}
       for group, items in groups})

これにより、次のことがわかります。

{'B': {'num2': 9, 'num3': 14, 'num1': 6}, 
 'A': {'num2': 10, 'num3': 6, 'num1': 8}}

値をタイプ別にソートし、グループに分割しますitertools.groupby()(複数回繰り返す必要があるため、ジェネレーターの代わりに項目リストを作成します)。

次に、ネストされた dict 内包表記を使用して必要なデータを作成し、アイテムの値を合計してグループに割り当てます。

これは、2 つ以上のタイプに拡張できる柔軟なソリューションです。

于 2013-04-21T14:54:40.877 に答える
0

ネストされた内包表記を使用します。

lst = [{"num1": 3, "num2": 8, "num3": 5, "type": "A"},
     {"num1": 2, "num2": 5, "num3": 5, "type": "B"},
     {"num1": 5, "num2": 2, "num3": 1, "type": "A"},
     {"num1": 4, "num2": 4, "num3": 9, "type": "B"}]

sum_by_a = {key: sum(d[key] for d in lst if d['type'] == 'A')
    for key in ("num1", "num2", "num3")}

または、ジェネリック型の場合、

sum_by_type = lambda t: {
    key: sum(d[key] for d in lst if d['type'] == t)
        for key in ("num1", "num2", "num3")}

 sum_by_b = sum_by_type(B)
于 2013-04-21T15:12:14.210 に答える
0

私はそのように行きCollections.Counterます:

from collections import Counter
from functools import reduce

l = [{"num1":3, "num2":8, "num3":5, "type":"A"},
     {"num1":2, "num2":5, "num3":5, "type":"B"},
     {"num1":5, "num2":2, "num3":1, "type":"A"},
     {"num1":4, "num2":4, "num3":9, "type":"B"}]

def remove_keys(d, keys):
    return {i: j for i, j in d.items() if i not in keys}

def add_dicts(dicts):
    return reduce(lambda a, b: a+b,  map(Counter, dicts))

tmp = {}
for d in l:
    tmp[d["type"]] = tmp.get(d["type"], []) + [remove_keys(d, ["type"])]

result = {key: add_dicts(value) for key, value in dict(tmp).items()}

与える:

{'A': Counter({'num2': 10, 'num1': 8, 'num3': 6}), 
'B': Counter({'num3': 14, 'num2': 9, 'num1': 6})}
于 2013-04-21T15:16:16.867 に答える