2014-02-14 1 views
2

간단한 플랫 목록을 중첩 목록에 복사하려고합니다. 예를 들면 다음과 같습니다.플랫 목록을 중첩 된 dict에 복사

from collections import OrderedDict 

simple_list = [5,6,7,8] 
nested_dict = OrderedDict([('item1', 1), ('item2', OrderedDict([('item3', 2), ('item4', {'item5': 3})])), ('item6',4)]) 

new_nested_dict = unflatten(nested_dict, simple_list) 
print new_nested_dict 

>>> OrderedDict([('item1', 5), ('item2', OrderedDict([('item3', 6), ('item4', {'item5': 7})])), ('item6',8)]) 

제 연구에서부터 발전기가 좋은 방법이라고 생각됩니다. 그러나 의사를 살펴본 후에는 내가 사용하고 싶은 것을 구현하는 방법에 대해서는 아직 명확하지 않습니다.

def unflatten(nested_items, flat_data, start=0):  
    if isinstance(nested_items, OrderedDict): 
     nested_items = nested_items.values() 
    idx = start 
    for x in nested_items:   
     if isinstance(x, Iterable): 
      for i in unflatten(x, flat_data, start=idx): 
       yield i 
     else: 
      idx += 1 
      yield flat_data[idx] 

누군가 내가 여기서 잘못하고있는 것을 지적 할 수 있습니까? 나는 완전히 다른 방식으로 즐겁게 기꺼이 나아 간다. 감사.

답변

0

난 당신이 일을 왜 몰라,하지만 난이 간단한 재귀 알고리즘이 작동 생각 : 기존 알고리즘에 관한

from collections import OrderedDict 

simple_list = [5,6,7,8] 
nested_dict = OrderedDict([('item1', 1), ('item2', OrderedDict([('item3', 2), ('item4', {'item5': 3})])), ('item6',4)]) 

def unflatten(nested_items, flat_data): 
    remaining_keys = list(nested_items.keys()) 
    while flat_data and remaining_keys: 
     key = remaining_keys.pop(0) 
     existing_value = nested_items[key] 
     if isinstance(existing_value, dict): 
      unflatten(existing_value, flat_data) 
     else: 
      nested_items[key] = flat_data.pop(0) 

    return nested_items 

new_nested_dict = unflatten(nested_dict, simple_list) 
assert new_nested_dict == OrderedDict([('item1', 5), ('item2', OrderedDict([('item3', 6), ('item4', {'item5': 7})])), ('item6',8)]) 

, 문제가 isinstance(nested_items, OrderedDict) 상태에있을 수있다. 적어도 하나의 오브젝트는 OrderedDict이 아니지만 일반 dict입니다. 저는 후자를 전 수퍼 클래스이기 때문에 코드에서 사용합니다.

또한 yield은 생성기 값을 반환합니다.이 값은 dicts보다 지연 목록과 더 밀접하게 관련되어 있습니다. 좀 더 간단한 맥락에서 그들과 함께 노는 것을 시도해보십시오.

0

는이 작업을 수행하여 장소에서 기존의 사전을 업데이트 할 수 있습니다 :이 새로운 중첩 딕셔너리를 산출하기보다는 장소에서 기존 주문 DICT를 업데이트하는 것이

from collections import OrderedDict, Mapping 

simple_list = [5,6,7,8] 
nested_dict = OrderedDict([('item1', 1), ('item2', OrderedDict([('item3', 2), ('item4', {'item5': 3})])), ('item6',4)]) 

def update(d, u): 
    for k, v in d.iteritems(): 
     if isinstance(v, Mapping): 
      update(d.get(k), u) 
     else: 
      try: 
       d[k] = u.pop(0) 
      except IndexError: 
       break 
    return d    

update(nested_dict, simple_list) 
print nested_dict 
# OrderedDict([('item1', 5), ('item2', OrderedDict([('item3', 6), ('item4', {'item5': 7})])), ('item6', 8)]) 

알 수 있습니다.

오래된 dict에 액세스하려면 deepcopy을 먼저 사용하십시오. 전달한 목록은 각 요소를 차례로 팝하여 소모됩니다. 다시 한 번, 해당 데이터를 보관해야하는 경우 - 목록의 슬라이스 나 다른 사본으로 사본을 만드십시오.

생성기를 생성하는 것이 효율적이지만 일반적으로 업데이트가 일반적으로 훨씬 효율적입니다.

관련 문제