2012-07-17 66 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