我在python中有一个dicts列表,如下所示:
midd()
如何获得列表的每个字典中的键的总和,以便我有:
[
{
"25-34": {
"Clicks": 10
},
"45-54": {
"Clicks": 2
},
},
{
"25-34": {
"Clicks": 20
},
"45-54": {
"Clicks": 10
},
}
]
我尝试使用{
"25-34": {
"Clicks": 30
},
"45-54": {
"Clicks": 12
},
}
,但是当Counter()
内部列表是平的时,它很容易,但是如上所述嵌套的dicts会出现此错误:
dicts
如何实现如上所述的求和。
注意:我已添加 /usr/lib/python2.7/collections.pyc in update(self, iterable, **kwds)
524 self_get = self.get
525 for elem, count in iterable.iteritems():
--> 526 self[elem] = self_get(elem, 0) + count
527 else:
528 super(Counter, self).update(iterable) # fast path when counter is empty
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
仅供参考。嵌套的dicts可以没有任何键,
另一个让它更清晰的例子:
clicks
输出:
[
{
"25-34": {
"Clicks": 10,
"Visits": 1
},
"45-54": {
"Clicks": 2,
"Visits": 2
},
},
{
"25-34": {
"Clicks": 20,
"Visits": 3
},
"45-54": {
"Clicks": 10,
"Visits": 4
},
}
]
答案 0 :(得分:5)
从你的编辑中,听起来你只是试图通过父词汇来总结所有子词的值:
In [9]: counts = Counter()
In [10]: for dd in data:
...: for k,v in dd.items():
...: counts[k] += sum(v.values())
...:
In [11]: counts
Out[11]: Counter({'25-34': 30, '45-54': 12})
从根本上说,这是一个笨拙的数据结构。
好的,鉴于您的上一次更新,我认为最简单的方法是使用defaultdict
Counter
工厂:
In [17]: from collections import Counter, defaultdict
In [18]: counts = defaultdict(Counter)
In [19]: for dd in data:
...: for k, d in dd.items():
...: counts[k].update(d)
...:
In [20]: counts
Out[20]:
defaultdict(collections.Counter,
{'25-34': Counter({'Clicks': 30, 'Visits': 4}),
'45-54': Counter({'Clicks': 12, 'Visits': 6})})
答案 1 :(得分:1)
我会使用defaultdict
,默认值为int
(即0):
from collections import defaultdict
counter = defaultdict(int)
for current_dict in data:
for key, value in current_dict.items():
counter[key] += sum(value.values())
在我看来,这是计算值的最可读方式。
答案 2 :(得分:1)
我没有列表理解的变体:
def my_dict_sum(data):
"""
>>> test_data = [{"25-34": {"Clicks": 10, "Visits": 1}, "45-54": {"Clicks": 2, "Visits": 2}, },{"25-34": {"Clicks": 20, "Visits": 3}, "45-54": {"Clicks": 10, "Visits": 4}, }]
>>> my_dict_sum(test_data)
{'45-54': {'Clicks': 12, 'Visits': 6}, '25-34': {'Clicks': 30, 'Visits': 4}}
"""
result_key = data[0]
for x in data[1:]:
for y in x:
if y in result_key:
for z in x[y]:
if z in result_key[y]:
result_key[y][z] = result_key[y][z] + x[y][z]
return result_key
答案 3 :(得分:0)
对于你的第一个问题,这里是一个单行。它不是很漂亮,但确实使用了Counter
:
sum((Counter({k:v['Clicks'] for k,v in d.items()}) for d in data), Counter())
举个例子:
data = [
{
"25-34": {
"Clicks": 10
},
"45-54": {
"Clicks": 2
},
},
{
"25-34": {
"Clicks": 20
},
"45-54": {
"Clicks": 10
},
}
]
from collections import Counter
c = sum((Counter({k:v['Clicks'] for k,v in d.items()}) for d in data), Counter())
print(c)
输出:
Counter({'25-34': 30, '45-54': 12})
答案 4 :(得分:0)
我确实这样:
with gzip.open("data/small_fasta.fa.gz", "rt") as handle:
aac_count = defaultdict(Counter)
for record in SeqIO.parse(handle, "fasta"):
aac_count[record.id].update(record.seq)
我用biopython打开了我经常使用的文件类型fasta文件(https://pt.wikipedia.org/wiki/Formato_FASTA)。
它有一个标头(“ proteinx”),在下一行是一个序列(dna或蛋白质串)。biopython是处理fasta文件的一种简便方法。
然后我将defaultdic和Counter用于集合。 Record.id是标题,是键,我用序列更新计数器,以计算字符串中给定字符的数量。
在我的情况下,输出是这样的:
defaultdict(collections.Counter,
{'UniRef100_Q6GZX4': Counter({'M': 6,
'A': 13,
'F': 8,
'S': 13,
'E': 15,
'D': 17,
'V': 21,
'L': 25,
'K': 29,
'Y': 14,
'R': 15,
'P': 11,
'N': 8,
'W': 4,
'Q': 9,
'C': 4,
'G': 15,
'I': 12,
'H': 9,
'T': 8}),
'UniRef100_Q6GZX3': Counter({'M': 7,
'S': 22,
'I': 10,
'G': 23,
'A': 26,
'T': 26,
'R': 16,
'L': 14,
'Q': 13,
'N': 9,
'D': 24,
'K': 17,
'Y': 11,
'P': 37,
'C': 18,
'F': 9,
'W': 6,
'E': 6,
'V': 23,
'H': 3}),...}