给定名称列表中关联数字的Python总和

时间:2012-08-21 15:55:06

标签: python

我有一份清单词典:

d = {'a': ['Adam', 'Book', 4], 'b': ['Bill', 'TV', 6, 'Jill', 'Sports', 1, 'Bill', 'Computer', 5], 'c': ['Bill', 'Sports', 3], 'd': ['Quin', 'Computer', 3, 'Adam', 'TV', 3], 'e': ['Quin', 'TV', 2, 'Quin', 'Book', 5], 'f': ['Adam', 'Computer', 7]}

每个列表表示此人使用给定对象的次数。例如,对于列表“a”,它表示Adam每周读取Book 4次。在“b”中,Bill每周观看TV 6次,“Jill”每周播放{{​​1}}次。

我想在每个列表中找到一个人做某事的总次数。

在这种情况下,输出将是这样的:

sports

不一定是那种确切的格式,而是类似的东西。

目前,我尝试过使用Counter,但它只计算人名,而不是与之相关的数字。我试过只返回名称然后返回数字,但这并不适用于名称超过1的列表,因为有些名称甚至有6个。

任何帮助表示赞赏!谢谢!

3 个答案:

答案 0 :(得分:3)

如果确实想要对您的数据结构执行此操作,您可以执行以下操作:

from collections import defaultdict

for k, lst in d.iteritems():
    counts = defaultdict(int)
    for i in range(0, len(lst), 3):
        counts[lst[i]] += lst[i + 2]
    print k, ", ".join(["%s %d" % (n, c) for n, c in counts.items()])

然而,更好的想法是将数据存储在合理的数据结构中。使用诸如“每个列表以三个组为一组,其中每个三个中的第一个是名称等”的规则在列表中存储信息使得使用数据笨拙和违反直觉。相反,如果您将数据存储为:

,该怎么办?
d = {'a': {'Adam': {'Book': 4}},
     'b': {'Bill': {'TV': 6, 'Computer': 5}, 'Jill': {'Sports': 1}},
     'c': {'Bill': {'Sports': 3}},
     'd': {'Quin': {'Computer': 3}, 'Adam': {'TV': 3}},
     'e': {'Quin': {'TV': 2, 'Book': 5}},
     'f': {'Adam': {'Computer': 7}}}

然后,你可以回答这样的问题:

for k, v in d.items():
    print k, ", ".join(["%s %d" % (n, sum(a.values())) for n, a in v.items()])

这也有许多其他好处:你可以通过做d["a"]["Adam"]["Book"](或者,如果你不确定“亚当”或“预订“有,d["a"].get("Adam", {}).get("Book", 0))。基于此列表的其他计算也是可行且有用的。

答案 1 :(得分:2)

我认为defaultdict和列表切片在这里很有用......

a = ['Adam', 'TV', 4, 'Adam', 'Bike', 4 ]
print a[::3] # ['Adam', 'Adam' ]
print a[2::3] # [4, 4]

from collections import defaultdict
for key,value in d.items():
    c = defaultdict(int)
    for k,v in zip(value[::3],value[2::3]):
        c[k] += v
    print key, c

Counter也可以工作,但是直到python2.7才会引入,而defaultdict与python2.5兼容并在此实例中提供相同的功能。

虽然正如其他人所说,这似乎是你正在使用的非常奇怪的数据结构......

答案 2 :(得分:0)

这会产生所需的结果:

import collections
for k, v in sorted(d.iteritems()):
        tmp=collections.defaultdict(int)
        for i in xrange(0, len(v), 3):
                tmp[v[i]]+=v[i+2]
        print "{}: {}".format(k,
                ", ".join("%s %s" % (a, b)
                        for a, b in sorted(tmp.iteritems())))

输出:

a: Adam 4
b: Bill 11, Jill 1
c: Bill 3
d: Adam 3, Quin 3
e: Quin 7
f: Adam 7