2011-09-25 4 views
1

아래의 파이썬 코드를 리팩토링하는 가장 좋은 방법을 찾고 있습니다. 2 ~ 3 줄의 코드에서이 작업을 수행하는 Python 방식이 있다고 생각합니다. 그러나이를 파악할 수는 없습니다. Stackoverflow를 검색했지만 유사한 문제와 솔루션을 찾을 수 없습니다. 많은 감사합니다!두 개의 튜플 목록을 병합하고 튜플에 고유하지 않은 값을 추가하는 Pythonic 방법은 무엇입니까?

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

왜 처음에는 dicts가 아닌 tuples 목록입니까? –

+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 

당신이 listtuple의 S하려는 경우 :

list3 = merged.items() 

당신이 chain없이하고 싶은 경우에, 당신은 그것을 할 수 있습니다 예 :

from collections import defaultdict 

merged = defaultdict(int) 

merged.update(list1) 

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

편집 : 베니으로 2.7/3.2 +에 댓글로 지적 할 수있다 : 당신이 dict s의 목록을 변환이 필요하지만, 그렇지 않으면 완벽

from collections import Counter 

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

.

+0

정말 고마워요! 천재! –

+2

2.7/3.2에서 [collections.Counter] (http://docs.python.org/dev/library/collections.html#counter-objects)가 더 좋습니다. –

+0

'Counter's는 'dict' 서브 클래스이므로 드롭 인 대체품으로 작동합니다. –

관련 문제