2012-07-17 6 views
1

이것은 긴 질문이므로 저와 함께주십시오. 3 개의 API에서 얻은 3 개의 dicts로 시작합니다.파이썬에서 다른 사전 병합하기

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 키를 추출하십시오 dicts는 구조과 같이 있습니다. 이 작업을 수행하려면 상당히 많은 처리가 필요하고 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() 기능.

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}, 
...} 

이는 다음과 같습니다

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} 

지금 내가해야 할 일을 새 사전과 같이 내가 가진 너무 API1, API2 또는 API3ScoredResults에서 URL의를 연결하는 것입니다 내가하기에는 너무 어렵다. 내 질문에 대한 역사를 되돌아 보면 수많은 사전 질문을하고 있지만 지금까지는 아무런 구현도 없었다. 누구든지 올바른 방향으로 나를 가리켜 주시면 감사하겠습니다. 주어진 데이터와

+0

다양한 API에서 반환 된 결과가 고유하다는 것을 보장 할 수 있습니까? 예를 들어, API2와 API3 모두에서 'www.dol.com'을 URL로 사용합니다. 실제 코드에서 실제로 가능합니까? 그렇다면 URL 만 지정하면 API2 또는 API3에서 온 것인지 여부를 알 수 없습니다. – mgilson

+0

@mgilson 예 중복은 URL에서 가능하지만 제목/스 니펫의 모든 버전에 만족합니다. 'API1의 url1이 제목 및 스 니펫을 가져오고, API2의 elif가 제목 및 스 니펫을 가져 오는 경우 ...' – adohertyd

+0

여러 API에 의해 반환 된 사전은 정말 간단합니까? (즉, 항상 하나의 키/값 쌍만 있습니까?) – mgilson

답변

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

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

+0

예를 들어,'snippet'가'API2'에서'excerpt'라고 불려지면 어떻게 될까요? 명확성을 위해서 구조가 여전히 동일합니까? – adohertyd

+0

@adohertyd - 그러면 더 복잡해지며 가능한 이름을 가리키는 매핑 사전을 정의해야합니다. – eumiro

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

+0

@adohertyd - 제목, 스 니펫 및 원본 사전에있는 모든 내용은 점수와 함께 마스터에 있어야합니다. 'master [url] [ 'title']'또는'master [url] [ 'snippet']' – mgilson

+0

아, 그래, 지금은 미안해. 나는이 단계에서 좌절감을 느끼지 않는다고 생각한다. 고맙습니다. – adohertyd

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

+0

''url ''또는''Url "'을 가질 수 있다면 적절하게 루프를 수정할 수있다. API의 각 항목에 대한 특정 키를 가정하지 않으면이 솔루션은 이미 게시 된보다 우아한 것보다 더 적응할 수 있습니다. –