Python 字典列表中按特定键分组的键值之和
我想对按范围分组的键的值求和Python 字典列表中按特定键分组的键值之和,python,list,dictionary,Python,List,Dictionary,我想对按范围分组的键的值求和 [ {'scope': u'internal', 'invoiced': 1000, 'initial_boq': 2800} {'scope': u'internal', 'invoiced': 2000, 'initial_boq': 1000} {'scope': u'internal', 'invoiced': 2000, 'initial_boq': 500} {'scope': u'external', 'invo
[
{'scope': u'internal', 'invoiced': 1000, 'initial_boq': 2800}
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 1000}
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 500}
{'scope': u'external', 'invoiced': 500, 'initial_boq': 1800}
{'scope': u'external', 'invoiced': 150, 'initial_boq': 200}
{'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}
]
如何在dict分组范围中获得键的总和,例如:
预期产量
[
{'scope': u'internal', 'invoiced': 5000, 'initial_boq': 4300},
{'scope': u'external', 'invoiced': 650, 'initial_boq': 2000},
{'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}
]
请告诉我如何才能达到同样的效果,因为您没有提供任何关于您以前尝试的信息。我假设这个问题是关于从哪里开始的 我要寻找的第一件事是一个数据结构,它使解决问题变得简单。在这种情况下,我将创建一个总和字典:
总和={
“内部”:{“发票”:…,“初始工程量清单”:…},
# …
}
特别适合这种情况的是defaultdict:
从集合导入defaultdict
总和=defaultdict(lamdba:defaultdict(lambda:0))
使用此定义,您可以添加如下值:
sums['internal']['invoited']+=1_值
您可以像这样使用itertools.groupby
。使用一个额外的函数来汇总分组项
from itertools import groupby
from operator import itemgetter
d = [
{'scope': u'internal', 'invoiced': 1000, 'initial_boq': 2800},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 1000},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 500},
{'scope': u'external', 'invoiced': 500, 'initial_boq': 1800},
{'scope': u'external', 'invoiced': 150, 'initial_boq': 200},
{'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000},
]
def getsummed(scope, elems):
d = {'scope': scope, 'invoiced': 0, 'initial_boq': 0}
for e in elems:
d['invoiced'] += e['invoiced']
d['initial_boq'] += e['initial_boq']
return d
def sortedgroupby(iterable, key):
return groupby(sorted(iterable, key=key), key=key)
print([getsummed(gpr, groups) for gpr, groups in sortedgroupby(d, key=itemgetter('scope'))])
结果是
[{'scope': 'internal', 'invoiced': 5000, 'initial_boq': 4300}, {'scope': 'external', 'invoiced': 650, 'initial_boq': 2000}, {'scope': 'both', 'invoiced': 5000, 'initial_boq': 7000}]
这里有一行:)
这是这一行的等效代码
key = lambda d: d['scope']
res = []
for scope,grps in groupby(sorted(lst, key=key), key=key):
c = Counter()
for grp in grps:
grp.pop('scope')
c += Counter(grp)
res.append(dict(c, scope=scope))
pprint(res)
再见
比这里已经发布的许多解决方案要不那么引人注目,但非常清楚
def removeDuplicatedScopesFrom(startingData):
differentScopes = []
for x in startingData:
scope = x["scope"]
if scope not in differentScopes:
differentScopes.append(scope)
return differentScopes
def composeDictionaryElement(scope, invoiced, initial_boq):
return("{'scope': u'" + scope + "', 'invoiced': " + str(invoiced) + ", 'initial_boq': " + str(initial_boq) + "}")
def main():
var = [
{'scope': u'internal', 'invoiced': 1000, 'initial_boq': 2800},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 1000},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 500},
{'scope': u'external', 'invoiced': 500, 'initial_boq': 1800},
{'scope': u'external', 'invoiced': 150, 'initial_boq': 200},
{'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}
]
# empty list for the final result
finalList = []
# identifying the different scopes involved
scopes = removeDuplicatedScopesFrom(var)
# scanning the input and joining data from the same scope
for scope in scopes:
# resetting values for each different scope
invoiced = 0;
initial_boq = 0;
# checking all the elements in the list
for y in var:
if y["scope"] == scope:
invoiced = invoiced + y["invoiced"]
initial_boq = initial_boq + y["initial_boq"]
# when list is over we ask to compose the related dictionary element
finalDictionaryElement = composeDictionaryElement(scope, invoiced, initial_boq)
# adding it to the final list
finalList.append(finalDictionaryElement)
# results out without surrounding quotes
print("[%s]" % (', '.join(finalList)))
if __name__== "__main__":
main()
输出
[{'scope': u'internal', 'invoiced': 5000, 'initial_boq': 4300}, {'scope': u'external', 'invoiced': 650, 'initial_boq': 2000}, {'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}]
希望这也有帮助 祝你今天愉快,
安东尼诺你以前解决这个问题的尝试是什么样子的?你可能希望熊猫来做这种手术。您可以使用常规代码执行此操作,但这正是pandas的用途。@PaulRooney[{'scope':u'internal','Invocated':5000,'initial_boq':4300}{'scope':u'external','Invocated':650,'initial_boq':2000}{'scope':u'both','Invocated':5000,'initial_boq':7000}它部分工作,我不知道为什么它给出了同一个键的两个dict的输出,即scope。感谢您的努力这可能是因为元素列表没有按
范围
属性排序。它在您的示例代码中。如果首先对groupby
的输入进行排序,则该操作将起作用。使用groupby(sorted(d,key=itemgetter('scope'))、key=itemgetter('scope'))
之类的代码会变得有点笨拙。因此,自定义分组函数可能是最好的。
def removeDuplicatedScopesFrom(startingData):
differentScopes = []
for x in startingData:
scope = x["scope"]
if scope not in differentScopes:
differentScopes.append(scope)
return differentScopes
def composeDictionaryElement(scope, invoiced, initial_boq):
return("{'scope': u'" + scope + "', 'invoiced': " + str(invoiced) + ", 'initial_boq': " + str(initial_boq) + "}")
def main():
var = [
{'scope': u'internal', 'invoiced': 1000, 'initial_boq': 2800},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 1000},
{'scope': u'internal', 'invoiced': 2000, 'initial_boq': 500},
{'scope': u'external', 'invoiced': 500, 'initial_boq': 1800},
{'scope': u'external', 'invoiced': 150, 'initial_boq': 200},
{'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}
]
# empty list for the final result
finalList = []
# identifying the different scopes involved
scopes = removeDuplicatedScopesFrom(var)
# scanning the input and joining data from the same scope
for scope in scopes:
# resetting values for each different scope
invoiced = 0;
initial_boq = 0;
# checking all the elements in the list
for y in var:
if y["scope"] == scope:
invoiced = invoiced + y["invoiced"]
initial_boq = initial_boq + y["initial_boq"]
# when list is over we ask to compose the related dictionary element
finalDictionaryElement = composeDictionaryElement(scope, invoiced, initial_boq)
# adding it to the final list
finalList.append(finalDictionaryElement)
# results out without surrounding quotes
print("[%s]" % (', '.join(finalList)))
if __name__== "__main__":
main()
[{'scope': u'internal', 'invoiced': 5000, 'initial_boq': 4300}, {'scope': u'external', 'invoiced': 650, 'initial_boq': 2000}, {'scope': u'both', 'invoiced': 5000, 'initial_boq': 7000}]