2013-08-01 126 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)