2012-07-17 86 views
1

這是一個很長的問題,請耐心等待。我從3個API獲得3個詞典開始。字典有這樣的結構:在Python中合併不同的字典

API1 = {'results':[{'url':'www.site.com','title':'A great site','snippet':'This is a great site'}, 
{'url':'www.othersite.com','title':'Another site','snippet':'This is another site'}, 
{'url':'www.wiki.com','title':'A wiki site','snippet':'This is a wiki site'}]} 

API2 = {'hits':[{'url':'www.dol.com','title':'The DOL site','snippet':'This is the dol site'}, 
{'url':'www.othersite.com','title':'Another site','snippet':'This is another site'}, 
{'url':'www.whatever.com','title':'Whatever site','snippet':'This is a site about whatever'}]} 

API3 = {'output':[{'url':'www.dol.com','title':'The DOL site','snippet':'This is the dol site'}, 
{'url':'www.whatever.com','title':'Whatever site','snippet':'This is a site about whatever'}, 
{'url':'www.wiki.com','title':'A wiki site','snippet':'This is a wiki site'}]} 

我從API1,API2和API3中提取URL鍵來做一些處理。我這樣做是因爲需要完成相當多的處理,並且只需要URL。完成後我有網址與刪除的重複和分數是相對於每個URL在列表中的位置的另一個列表的列表:

URLlist = ['www.site.com','www.wiki.com','www.othersite.com','www.dol.com','www.whatever.com'] 

Results = [1.2, 6.5, 3.5, 2.1, 4.0] 

我所做的創建從這些2列出了使用新字典功能zip()

ScoredResults = dict(zip(URLlist,Results))

{'www.site.com':1.2,'www.wiki.com':6.5, 'www.othersite.com':3.5, 'www.dol.com':2.1, 'www.whatever.com':4.0} 

現在我需要做的就是URL的從ScoredResultsAPI1API2API3鏈接,這樣我有一個新的字典,像這樣:

Full Results = 
{'www.site.com':{'title':'A great site','snippet':'This is a great site','score':1.2}, 
'www.othersite.com':{'title':'Another site','snippet':'This is another site','score':3.5}, 
...} 

這是對我來說太難了。如果你回顧我的問題歷史,我一直在問很多字典問題,但迄今爲止還沒有實現工作。如果任何人都可以請指出我正確的方向,我將非常感激。

+0

你能得到保證,結果在不同API返回的是獨一無二的?例如,在API2和API3中都有'www.dol.com'作爲URL。這是真的可能在你的真實代碼?如果是這樣,只要給出URL,就不可能知道它是來自API2還是API3。 – mgilson 2012-07-17 12:53:23

+0

@mgilson是複製是可能的URL的,但我會很樂意與標題/段的任意版本,以便像'如果爲url1在API1得到API2標題和摘要,ELIF獲得標題和摘要...' – adohertyd 2012-07-17 12:56:37

+0

是各種API返回的字典真的很簡單嗎? (即,他們總是隻有一個鍵/值對?) – mgilson 2012-07-17 12:59:46

回答

1

快速嘗試:

from itertools import chain 

full_result = {} 

for blah in chain.from_iterable(d.itervalues() for d in (API1, API2, API3)): 
    for d in blah: 
     full_result[d['url']] = { 
      'title': d['title'], 
      'snippet': d['snippet'], 
      'score': ScoredResults[d['url']] 
     } 

print full_result 
+0

謝謝你。我一直在嘗試'itertools',這是一個很好的使用它。將保持這種方法! – adohertyd 2012-07-17 13:09:23

1

在給定的數據...

Full_Results = {d['url']: {'title': d['title'], 'snippet': d['snippet'], 'score': ScoredResults[d['url']]} for d in API1['results']+API2['hits']+API3['output']} 

導致成:

{'www.dol.com': {'score': 2.1, 
    'snippet': 'This is the dol site', 
    'title': 'The DOL site'}, 
'www.othersite.com': {'score': 3.5, 
    'snippet': 'This is another site', 
    'title': 'Another site'}, 
'www.site.com': {'score': 1.2, 
    'snippet': 'This is a great site', 
    'title': 'A great site'}, 
'www.whatever.com': {'score': 4.0, 
    'snippet': 'This is a site about whatever', 
    'title': 'Whatever site'}, 
'www.wiki.com': {'score': 6.5, 
    'snippet': 'This is a wiki site', 
    'title': 'A wiki site'}} 
+1

你的編輯已經清除了我的謝謝 – adohertyd 2012-07-17 12:58:54

+0

如果'snippet'在'API2'中被稱爲'excerpt'例如?只是爲了清楚起見,結構還是一樣的嗎? – adohertyd 2012-07-17 13:08:14

+0

@adohertyd - 然後它變得更加複雜,你將不得不定義映射字典指向可能的名稱。 – eumiro 2012-07-17 13:12:29

2

我將改變API的到的東西,是更有意義的你。 URL的字典可能更合適:

def transform_API(API): 
    list_of_dict=API.get('results',API.get('hits',API.get('output'))) 
    if(list_of_dict is None): 
     raise KeyError("results, hits or output not in API") 
    d={} 
    for dct in list_of_dict: 
     d[dct['url']]=dct 
     dct.pop('url') 
    return d 

API1=transform_API(API1) 
API2=transform_API(API2) 
API3=transform_API(API3) 

master={} 
for d in (API1,API2,API3): 
    master.update(d) 

urls=list(master.keys()) 
scores=get_scores_from_urls(urls) 

for k,score in zip(urls,scores): 
    master[k]['score']=score 
+0

謝謝你,但它不能解決我的標題和片段到一個新的字典中的問題? – adohertyd 2012-07-17 13:28:20

+0

@adohertyd - 原始字典中的標題,片段和其他所有內容應與主題一起成爲主角。 '主[url] ['title']'或'主[url] ['snippet']' – mgilson 2012-07-17 13:35:56

+0

啊,我現在看到對不起,我覺得我在這個階段被挫敗矇蔽了!謝謝 – adohertyd 2012-07-17 13:38:02

1

會像你的工作?這是相當基本的,通過在URLlist上循環構建您的最終字典。

API1r = API1['results'] 
API2r = API2['hits'] 
API3r = API3['output'] 

FullResults = {} 
for (U, R) in zip(URLlist, Results): 
    FullResults[U] = {} 
    for api in (API1r, API2r, API3r): 
     for v in api: 
      k = dict() 
      k.update(v) 
      if (k.pop('url') == U): 
       FullResults[U].update((k.items()+[('score', R)])) 

注意,作爲同url可能存在於你的不同API秒,但與不同的信息,我們需要事先創建在FullResults相應的條目,所以它可能是一個有點棘手簡化循環。 LMKHIW。

+0

是的,這將是一個問題,所以它不會那麼簡單。但是我確實可以使其工作 – adohertyd 2012-07-17 13:33:27

+0

,如果你可以有''url「'或'Url'',你可以相應地修改這個循環。請注意,不要假設每個「API」項的特定鍵都會使此解決方案比已發佈的更優雅的解決方案更具適應性。 – 2012-07-17 13:36:34