2013-07-25 3 views
1
예를 들어

나는 두 dicts 있습니다파이썬에서 중첩 된 두 개의 사전을 병합하는 방법은 무엇입니까?

schema = { 
    'type': 'object', 
    'properties': { 
     'reseller_name': { 
      'type': 'string', 
     }, 
     'timestamp': { 
      'type': 'integer', 
     }, 
    }, 
    'required': ['reseller_name', 'timestamp'], 
} 

schema_add = { 
    'properties': { 
     'user_login': { 
      'type': 'string', 
     }, 
    }, 
    'required': ['user_login'], 
} 

을 나는 옆에 얻을 결과 DICT 추가와 통합 할 수 있습니다 방법 :

schema_result = { 
    'type': 'object', 
    'properties': { 
     'reseller_name': { 
      'type': 'string', 
     }, 
     'timestamp': { 
      'type': 'integer', 
     }, 
     'user_login': { 
      'type': 'string', 
     }, 
    }, 
    'required': ['reseller_name', 'timestamp', 'user_login'], 
} 

규칙 :

같은 경로를 0123의 경우는 properties이고 required 인 경우 예를 들어,및 scheme_add.

  1. 두 명령 모두에 동일한 경로가있는 명령이있는 경우 동일한 규칙으로 병합됩니다.
  2. 둘 다 dict에 동일한 경로가있는 목록이있는 경우 첫 번째 목록에 초를 추가하십시오.
  3. dict에 동일한 값 (또는 dict 및 non-dict 또는 list 및 nonlist)이 동일한 경로로 있으면 첫 번째 값이 두 번째 값으로 대체됩니다.
  4. 하나의 dict만이 키와 값을 설정하는 것보다 경로가있는 키가있는 경우.
+0

질문에 대한 답을 얻은 것 같습니다. 나열된 규칙은 * 귀하의 답변입니다. 이 문제를 구현하는 데 문제가 있습니까? 그렇다면 정확한 문제는 무엇입니까? –

+0

나는 규칙을 나열하기 전에 어려워 보였다. 이제 @ Nicolas78 도움으로 해보겠습니다. – tbicr

답변

2

문제가 어디에서 맘에 들지는 모르겠지만 작성 방법은 컴퓨터 프로그램과 거의 같으며 예제는 테스트 사례와 같습니다. 왜 이래서 시작하지 그래?

def add_dict(d1, d2): 
    newdict = {} 
    for (key, value) in d1.iteritems(): 
     if key in d2: ... 
      #apply rules, add to newdict, use 
     else: 
      #simply add 
    for (key, value) in d2.iteritems(): 
     if not key in d1: 
      # simply add 
    return newdict 

이것은 더 단단하게 작성 될 수 있지만 편집하기가 더 쉬울 수 있습니다. 마지막 코멘트를 작성 후, 도움이되지만 더 좋은 구현을 쓸 수 없습니다

편집 ..

def merge_values(a,b): 
    if a==None or b==None: 
     return a or b 
    # now handle cases where both have values 
    if type(a)==dict: 
     return add_dict(a, b) 
    if type(a)==list: 
     ... 

def add_dict(d1,d2): 
    return dict(
     [ 
      (key, 
      merge_values(
       d1.get(key,None), 
       d2.get(key,None))) 
      for key 
      in set(d1.keys()).union(d2.keys()) 
     ]) 
2

Nicolas78 도움 @내 자신의 솔루션 :

def merge(obj_1, obj_2): 
    if type(obj_1) == dict and type(obj_2) == dict: 
     result = {} 
     for key, value in obj_1.iteritems(): 
      if key not in obj_2: 
       result[key] = value 
      else: 
       result[key] = merge(value, obj_2[key]) 
     for key, value in obj_2.iteritems(): 
      if key not in obj_1: 
       result[key] = value 
     return result 
    if type(obj_1) == list and type(obj_2) == list: 
     return obj_1 + obj_2 
    return obj_2 
+2

'result = dict (obj_2)'를 설정하면 두 번째 for 루프 전체를 제거 할 수 있습니다. – RussW

+1

'result = obj_2.copy()'더 빨리 – tbicr

+0

아, 나는 단지 당신이 질문자라는 것을 눈치 채 셨습니다. – RussW

2

나는 간단하게 추가하고 이 문제의 해결책. 샘플 데이터가 변경되지 않는다고 가정합니다.

0

키를 정확히 알고있는 경우 사용해보십시오.

schema['properties'].update(schema_add['properties']) 
schema['result'].append(schema_add['result']) 

결과가 스키마에 병합됩니다.

키를 정확히 모르는 경우 내부 목록과 사전을 찾으려면 루프가 하나 필요합니다.

for value in schema: 
    if value is dict: 
     if schema_add.has_key(value) and schema_add[value] is dict: 
      schema[value].update(schema_add[value]) 
    elif value is list: 
     if schema_add.has_key(value) and schema_add[value] is list: 
      schema[value].append(schema_add[value]) 

결과를 다른 dict에도 병합 할 수 있습니다.

관련 문제