2011-09-25 24 views
1

我正在尋找重構下面的Python代碼的最佳方式。我認爲在2或3行代碼中有這樣一種Pythonic方法,但是無法弄清楚。我搜索了Stackoverflow,但找不到類似的問題和解決方案。非常感謝!什麼是Pythonic的方式來合併2個元組列表並添加元組中的非唯一值?

list1 = [(Python, 5), (Ruby, 10), (Java, 15), (C++, 20)] 
list2 = [(Python, 1), (Ruby, 2), (Java, 3), (PHP, 4), (Javascript, 5)] 

# I want to make an unsorted list3 like this 
# list3 = [(Python, 6), (Ruby, 12), (Java, 18), (PHP, 4), (Javasript, 5), (C++, 20)] 
common_keys = list(set(dict(list1).keys()) & set(dict(list2).keys())) 

if common_keys: 
    common_lst = [(x, (dict(list1)[x] + dict(list2)[x])) for x in common_keys] 
    rest_list1 = [(x, dict(list1)[x]) for x in dict(list1).keys() if x not in common_keys] 
    rest_list2 = [(x, dict(list2)[x]) for x in dict(list2).keys() if x not in common_keys] 
    list3 = common_lst + rest_list1 + rest_list2 

else: 
    list3 = list1 + list2 
+0

爲什麼他們首先列出元組而不是字典? –

+0

他們是Django values_lists :) –

+0

那麼你爲什麼不在ORM中這樣做? –

回答

5

您正在尋找collections.defaultdict

from collections import defaultdict 
from itertools import chain 

merged = defaultdict(int) 

for key, value in chain(list1, list2): 
    merged[key] += value 

如果你想tuplelist S:

list3 = merged.items() 

如果你想這樣做沒有chain,你可以做到這一點as:

from collections import defaultdict 

merged = defaultdict(int) 

merged.update(list1) 

for key, value in list2: 
    merged[key] += value 

編輯:作爲貝尼在評論中指出,在2.7/3.2 +,你可以這樣做:

from collections import Counter 

merged = Counter(dict(list1)) 
merged.update(dict(list2)) 

這就需要你轉換列表來dict秒,但在其他方面完美。

+0

非常感謝!天才! –

+2

在2.7/3.2上,[collections.Counter](http://docs.python.org/dev/library/collections.html#counter-objects)更好。 –

+0

'計數器'是'dict'子類,所以它可以作爲一個插入式替代品。 –

相關問題