1

我有一个形式的python字典:

a1 = {
        'SFP_1': ['cat', '3'], 
        'SFP_0': ['cat', '5', 'bat', '1']
     }

我需要的最终结果是以下形式的字典:

{'bat': '1', 'cat': '8'}

我目前正在这样做:

b1 = list(itertools.chain(*a1.values()))
c1 = dict(itertools.izip_longest(*[iter(b1)] * 2, fillvalue=""))

这给了我输出:

>>> c1
{'bat': '1', 'cat': '5'}

我可以遍历字典并得到它,但任何人都可以给我一种更 Python 的方式来做同样的事情吗?

4

5 回答 5

6

使用defaultdict

import itertools
from collections import defaultdict

a1 = {u'SFP_1': [u'cat', u'3'], u'SFP_0': [u'cat', u'5', u'bat', u'1']}

b1 = itertools.chain.from_iterable(a1.itervalues())
c1 = defaultdict(int)
for animal, count in itertools.izip(*[iter(b1)] * 2):
    c1[animal] += int(count)
# c1 => defaultdict(<type 'int'>, {u'bat': 1, u'cat': 8})

c1 = {animal: str(count) for animal, count in c1.iteritems()}
# c1 => {u'bat': '1', u'cat': '8'}
于 2013-08-01T06:52:00.770 回答
2
In [8]: a1 = {                               
        'SFP_1': ['cat', '3'], 
        'SFP_0': ['cat', '5', 'bat', '1']
     }

In [9]: answer = collections.defaultdict(int)

In [10]: for L in a1.values():                
    for k,v in itertools.izip(itertools.islice(L, 0, len(L), 2), 
                              itertools.islice(L, 1, len(L), 2)):
        answer[k] += int(v)

In [11]: answer
Out[11]: defaultdict(<type 'int'>, {'bat': 1, 'cat': 8})

In [12]: dict(answer)
Out[12]: {'bat': 1, 'cat': 8}
于 2013-08-01T06:51:17.190 回答
0

尝试collections.defaultdict(int): 从手册 -

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]

这应该可以让你到达你需要去的地方。

于 2013-08-01T06:56:55.207 回答
0

对于纯 Python 解决方案的价值,这里有一个。

a1 = {'SFP_1': ['cat', '3'], 'SFP_0': ['cat', '5', 'bat', '1']}

def count(what):
    sums = {}
    for items in what.itervalues():
        for k, v in zip(items[::2], items[1::2]):
            if k in sums:
                sums[k] = str(int(sums[k]) + int(v))
            else:
                sums[k] = v

    return sums

count(a1)给出,{'bat': '1', 'cat': '8'}.

于 2013-08-01T07:08:18.760 回答
0

您可以使用collections.Counter类,它基本上是 collections.defaultdict(int) 的一个特殊版本,带有漂亮的额外方法和漂亮的名称:

from collections import Counter


def count(dct):
    # Counter is specialized version of defaultdict(int)
    counter = Counter()
    for values in dct.viewvalues():
        assert len(values) % 2 == 0, "{!r} must have even length".format(values)
        # iterate by pairs
        for i in xrange(0, len(values) - 1, 2):
            counter[values[i]] += int(values[i + 1])
    # convert frequencies to strings
    return {word: str(freq) for word, freq in counter.viewitems()}


if __name__ == "__main__":
    a1 = {"SFP_1": ["cat", "3"],
          "SFP_0": ["cat", "5", "bat", "1"]
          }
    print count(a1)
于 2013-08-01T15:33:27.207 回答