2013-08-01 86 views
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'} 

我可以迭代字典,并得到这个,但任何人都可以给我一个更pythonic的方式做同样的?

+1

我还以为你在输出通缉“8”,而不是' 5' 。 (你真的想把它作为一个字符串,如果你添加数字吗?为什么不是一个int?) –

回答

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'} 
+1

'chain'的荣誉。希望我能想到那个 – inspectorG4dget

+0

Clean!谢谢:) – cisnik

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} 
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)] 

这应该让你得到你需要的人。

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'}

+0

'dict_obj.has_key(key)'已弃用。改为使用'dict_obj'中的键。 – falsetru

+0

请注意,如果您不需要它们作为字符串结束,代码会更简单一些。 'if'后面的第一行是'summs [k] + = int(v)',第二行:'summs [k] = int(v)'。 – FakeRainBrigand

+0

@falsetru,谢谢。我与另一种语言混在一起,并尝试'总有k'(它不太喜欢)。 – FakeRainBrigand

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)