2

我的数据是制表符分隔的,如下所示:

Name   Count    Sample
Dog    .0001    1
Dog    .00003   1
Dog    .0001    2
Cat    .0004    1
Cat    .0002    1
Cat    .0003    2
Cat    .0002    2

在我将变量 unid 定义为与第三列(ex Dog_1)合并的第一列并将 num 定义为该行的 Count 之后,我将每个 num 附加到 unid 下的字典中(使用 Python 2.7),如下所示:

for line in K:
        sp = line.split("\t")
        name = sp[0]
        unid = sp[3][:-2] +"_"+ sp[0]
        num = int(Decimal(sp[1]))
        if not dict1.has_key(unid):
            dict1[unid] = []
        dict1[unid].append(num)

我试着用这个来总结:

dictTot = sum(dict1.values())

但我收到此错误消息:

TypeError: unsupported operand type(s) for +: 'int' and 'list'

我怎样才能总结这些值,以便我可以检索Cat_1: .0006, Cat_2: .0005 等?

对不起大家,我知道我的?不是很好。但正如下面 Jacob 所说,“dictTot = sum(sum(value) for value in dict1.values())”对所有总和进行求和,但我正在寻找的是独立地对每个键下的每组值求和所以我可以找出样本 1 中有多少只猫,依此类推。也许 sum 不适合这个?对不起,很明显我不是一个非凡的 Python。

4

5 回答 5

2

不是这样的sum。你试图通过“添加”一堆列表来获得一个整数(或数值类型),所以内置函数吓坏了。试试这个:

dictTot = sum(sum(value) for value in dict1.values())

这将总结所有的总和,这就是你想要的(我认为)。

编辑

显然,您想对列表中每个元素中的所有值求和。为此,您可以使用字典理解

dictTot = {key:sum(l_values) for key, l_values in dict1.items()}
于 2012-06-29T20:01:31.430 回答
1

我基本上重写了整个事情......

K = "Dog    .0001    1\n  Dog    .00003   1\n  Dog    .0001    2\n  Cat    .0004   1\n  Cat    .0002    1\n  Cat    .0003    2\n  Cat    .0002    2"
dict1 = {}
for line in K.split("\n"):
    sp = line.split()
    name = sp[0]
    unid = "_".join([sp[0] , sp[2][-2:]])
    num = float(sp[1])
    if not dict1.has_key(unid):
        dict1[unid] = [num,]
    else :
        dict1[unid].append(num)
print(dict1)
dictTot = sum([sum(x) for x in dict1.values()])
print(dictTot)

最终的命令是

{'Dog_2': [0.0001], 
 'Dog_1': [0.0001, 3e-05], 
 'Cat_1': [0.0004, 0.0002], 
 'Cat_2': [0.0003, 0.0002]}

总和是

0.00133

这些值是列表,因此您希望循环它们以单独求和。

编辑

显然现在你想要“Cat_1:.0006,Cat_2:.0005 等”,所以dict1,你可以做

for key in dict1.iterkeys():
    dict1[key] = sum(dict1[key])

现在dict1变成

{'Dog_2': 0.0001, 
 'Dog_1': 0.00013, 
 'Cat_1': 0.0006, 
 'Cat_2': 0.0005}
于 2012-06-29T20:04:29.327 回答
1

为了对所有值求和,您必须首先将所有列表连接到一个sum()可以处理的迭代中。这里有两种方法可以做到这一点:

dictTot = sum(sum(dict1.values(), []))

稍微更冗长,但更具可读性:

from itertools import chain
dictTot = sum(chain.from_iterable(dict1.values()))

sum()实际上需要两个参数。第二个参数,start默认为0. 因此,您收到有关添加intto的错误消息list。本质上,它是这样做的:0 + [1, 2, 3] + [1, 2].... 在我的第一个示例中,我将默认起始值​​设置为一个空列表。结果是一个列表。现在我将所有值都放在一个列表中,我可以sum()通过结果来获得答案。

编辑

回应您的更新:

您可以使用生成器表达式执行此操作:

dictTot = {key: sum(value) for key, value in dictTot.items()}

或者如果您使用的是 < Python 2.7:

dictTot = dict((key, sum(value)) for key, value in dictTot.iteritems())
于 2012-06-29T20:12:28.790 回答
0

回答:

dict((k,sum(v)) for k,v in dict1.iteritems())

是的,更改int(Decimal('.0001'))并使用默认字典

+1 对一个有否决票的问题,然后是四个错过了 oneliner 答案的答案

编辑哎呀,我错过了@Joel Cornett 有它,所以那里也有道具

于 2012-06-29T20:59:06.287 回答
0

这有效:

d={}
for line in K:
   sp = line.strip().split()
   unid = sp[0]+"_"+sp[-1] 
   num = decimal.Decimal(sp[1])
   d.setdefault(unid,[]).append(num)      

print({k:sum(v) for k, v in d.items()})

印刷:

{'Dog_1': Decimal('0.00013'), 
 'Cat_2': Decimal('0.0005'), 
 'Cat_1': Decimal('0.0006'), 
 'Dog_2': Decimal('0.0001')}
于 2012-06-29T21:31:40.670 回答