2015-07-21 106 views
2

這是我的列表元組對象。它包括重複和相同的密鑰是a如何合併具有列表元組對象的鍵值

a = [("a",1), ("b",3), ("a",5)] 

dict_a = dict(a) 

print dict_a 
# {'a': 5, 'b': 3} 

但我希望我可以得到:

# {'a': 6, 'b': 3} 

如果我不使用forwhile來解決,我可以使用內置的功能呢?

回答

2

我想不出一個基本的解決方案,會比一個簡單的循環更好。這將是一個糟糕的解決方案:

from itertools import chain 
from collections import Counter 

a = [("a",1), ("b",3), ("a",5)] 

dict_a = dict(Counter(chain.from_iterable(map(lambda a: a[0] * a[1], a)))) 

print dict_a 
# {'a': 5, 'b': 3} 

這可以變得更糟,並進一步簡化聯接:

dict_a = dict(Counter("".join(map(lambda a: a[0] * a[1], a)))) 

而且進一步簡化應該列出壓縮不破for規則:

dict_a = dict(Counter("".join(b[0] * b[1] for n in a)))) 

如果我們導入乘法運算符,縮短(排序)。

from operator import mul 
dict_a = dict(Counter("".join(mul(*b) for b in a))) 

另一種可怕的想法是刪除Count和使用次數,但requies我們使用一個變量。

b = "".join(mul(*b) for b in a) 
dict_a = {e[0]: b.count(e) for e in b} 

雖然我們可能只是遍歷a成一個字典,計數,因爲我們走:

from operator import itemgetter 
dict_a = {e[0]: sum(map(itemgetter(1), filter(lambda a: a[0] == e[0], a))) for e in a} 
1
def dict_sum(a, totals=defaultdict(int)): 
    k, v = a.pop() 
    totals[k] += v 
    return totals if not a else dict_sum(a, totals) 
a = [("a",1), ("b",3), ("a",5)] 
res = dict_sum(a) 
print res 

輸出:

defaultdict(<type 'int'>, {'a': 6, 'b': 3}) 
2

個人而言,我會去這樣的解決方案:

import collections 

dict_a = collections.defaultdict(int) 
for k, v in a: 
    dict_a[k] += v 

但是,如果你」真的很想這樣做,這裏是一個沒有for/while循環的解決方案:)

import collections 

dict_a = collections.Counter(sum(map(lambda (x, y): (x,) * y, a),())) 
+0

這是一個很好的答案,但筆者沒有提到他不想使用for或while循環。 – matthewatabet

+2

@matthewatabet:我知道,但我仍然建議這:)其他解決方案實際上都使用循環,他們只是更好地隱藏它;) – Wolph

+0

是的,你是絕對正確的:)這是一個有趣的精神位試圖不直接使用循環的體操...但實際上這個答案是最容易閱讀的。 – matthewatabet

2

你可以使用內置的map()功能和部分:

from functools import partial 


def accum(memo, key_value): 
    key, value = key_value 
    memo[key] = value + memo.get(key, 0) 
    return key, memo[key] 

a = [("a", 1), ("b", 3), ("a", 5)] 

dict_a = dict(map(partial(accum, {}), a)) 

print dict_a 
>>> {'a': 6, 'b': 3} 
+1

這絕對是一個創意選項,從我+1:P – Wolph

相關問題