2017-04-21 1 views
1

<word: dictionary> 쌍을 포함하는 찾아보기 표가 있습니다. 그러면 단어 목록이 주어지면 이 룩업 테이블을 사용하여 사전 목록을 생성 할 수 있습니다. (이 단어 목록의 길이는 매번 고정되어 있지 않습니다.) 이러한 사전의 값은 일부 키의 로그 확률을 나타냅니다. 우리는 룩업 테이블을 확인하고소프트 결합 논리를 사용하여 사전 병합 속도 향상

dict_list = [{'apple':-1, 'flower':-2}, {'apple':-3, 'dog':-1}, {'apple':-2, 'flower':-1}] 수 있습니다

단어 목록

['fruit','animal','plant']을 감안할 때

: 여기

은 예입니다. 우리는 키 세트가 목록에서 볼 수 있습니다

: 각 키에 대한 {'apple', 'flower', 'dog'}

, 나는 dict_list의 각 값의 합을주고 싶다. 키가 하나의 사전에 존재하지 않는다면 값에 작은 값 -10을 추가합니다 (-10은 매우 작은 로그 확률로 간주 할 수 있습니다). 여기

'dog' = (-10) + (-1) + (-10) 내 python3 코드 dict_merge = {'apple':-6, 'flower':-13, 'dog':-21}입니다 , 'apple' = (-1) + (-3) + (-2), 'flower' = (-2) + (-10) + (-1) 때문에 : 같은

결과 사전 보인다

dict_list = [{'apple':-1, 'flower':-2}, {'apple':-3, 'dog':-1}, {'apple':-2, 'flower':-1}] 

key_list = [] 
for dic in dict_list: 
    key_list.extend(dic.keys()) 

dict_merge = dict.fromkeys(key_list, 0) 
for key in dict_merge: 
    for dic in dict_list: 
     dict_merge[key] += dic.get(key, -10) 

이 코드는 작동하지만, 만약 어떤 사전의 크기 dict_list은 매우 큽니다 (예 : 100,000). 실제로는 허용되지 않는 200ms 이상 걸릴 수 있습니다.

주요 계산은 for key in dict_merge 루프에 있으며 크기가 100,000 인 루프라고 가정합니다.

속도 향상 솔루션이 있습니까? 감사! 그리고 독서를 해 주셔서 감사합니다 ~ 어쩌면 너무 길고 성가시다 ...

P. 룩업 테이블에는 초대형 크기의 사전이 몇 개 있습니다. 그래서 여기에 몇 가지 기회가있을 수 있습니다.

답변

2

내가 이해할 수 있듯이 sum(len(d) for d in dict_list)len(key_list) * len(dict_list)보다 훨씬 작습니다.

from collections import defaultdict 

dict_list = [{'apple':-1, 'flower':-2}, {'apple':-3, 'dog':-1}, {'apple':-2, 'flower':-1}] 

default_value = len(dict_list) * (-10) 
dict_merge = defaultdict(lambda: default_value) 
for d in dict_list: 
    for key, value in d.items(): 
     dict_merge[key] += value + 10 
+0

정말 좋은 답변 그게 전부 - 당신이 원래 알고리즘 어떻게 다른지 자세한 내용을 설명 할 수있는 이유는 궁극적으로 동일한 결과를 – spacepickle

+0

감사를 생성합니다! 예, 이것은 더 빠릅니다. 그러나'len (dict_list)'는 항상 3보다 작고 끝에있는 keys_number를 스캔해야하므로 속도가 그렇게 빠르지는 않습니다. –

+0

@DongxuZhang 답변을 업데이트했습니다. 이제 키를 두 번 반복 할 필요가 없습니다. – f1u77y