2016-07-14 1 views
1

저는 파이썬에 상당히 익숙하며, 깊이있는 사전을 사용하여 최종 결과물로 필터 쿼리를 작성하려고합니다. 그 안에는 다른 사전과 목록이 있습니다. ! 나는이 Q 물체와 함께 A + (B 또는 C) + (D 또는 E)로 번역하는 것입니다 바라고파이썬에서 목록과 다른 사전을 포함하는 깊게 중첩 된 사전을 트래버스 할 수 있습니까?

filters = { 
    predicate: 'AND', 
    filters: [ 
     {'property_class_id': 10, operator: 'contains', operands: ['FOO']}, 
     { 
      predicate: 'NOT', 
      filters: [{ 
       predicate: 'OR', 
       filters: [ 
        {'property_class_id': 1, operator: 'contains', operands: ['Hello']}, 
        {'property_class_id': 2, operator: 'contains', operands: ['my search term']} 
       ] 
      }] 
     }, 
     { 
      predicate: 'OR', 
      filters: [ 
       {'property_class_id': 3, operator: 'contains', operands: ['my search term']}, 
       {'property_class_id': 4, operator: 'contains', operands: ['my search term']} 
      ] 
     } 
    ] 
} 

:

이 내 구조입니다.

하지만 첫 번째 문제는이 사전을 통과하여 각 키 값 쌍을 통과하는 방법입니다.

이것은 내가 지금까지 가지고 있지만 for 루프가 사전을 허용하기 때문에 목록에 도달하면 제한 사항을 볼 수 있습니다.

def unpack_filter(self, filters): 
    q_object = Q() 
    q_list = [] 

    for key, value in filters.iteritems(): 
     if isinstance(value, list) or isinstance(value, dict): 
      self.unpack_filter(value) 
     else: 
      print "{0} : {1}".format(key, value) 

답변

0

구조가 약간 변경되어 실행됩니다. 당신은 단순히 코드에 수정 된 unpack_filter 루프를 통합 할 수 있습니다 : 이전의 대답에 명시된 바와 같이 당신이 목록에서 사전 또는 항목에 하나 키를 통해 루프에 '의'연산자를 사용할 수 있습니다

base_filter = { 
    'predicate': 'AND', 
    'filters': [ 
    {'property_class_id': 10, 'operator': 'contains', 'operands': ['FOO']}, 
    { 
     'predicate': 'NOT', 
     'filters': [{ 
     'predicate': 'OR', 
     'filters': [ 
      {'property_class_id': 1, 'operator': 'contains', 'operands': ['Hello']}, 
      {'property_class_id': 2, 'operator': 'contains', 'operands': ['my search term']} 
     ] 
     }] 
    }, 
    { 
     'predicate': 'OR', 
     'filters': [ 
     {'property_class_id': 3, 'operator': 'contains', 'operands': ['my search term']}, 
     {'property_class_id': 4, 'operator': 'contains', 'operands': ['my search term']} 
     ] 
    } 
    ] 
} 

# try to avoid using/overwriting the 'filter' name as it's a built-in function 
# https://docs.python.org/2/library/functions.html#filter 
# this is why I'm using names such as 'curr_filter' and 'f' 

def unpack_filter(curr_filter): 
    # ... do something with curr_filter['predicate'] ... 
    for f in curr_filter['filters']: 
    if 'filters' in f: 
     unpack_filter(f)  
    else: 
     for key, value in f.iteritems(): 
     print '{0} : {1}'.format(key, value) 

unpack_filter(base_filter) 
0

. 이렇게하면 응답하는 방법을 결정하는 if 문과 함께 하나의 루프를 가질 수 있습니다. 위의 대답은 원하는 내용 일 수있는 가장 안쪽의 사전의 키와 값을 인쇄합니다. 'filters'또는 'predicates'가 키가 아닌 경우에만 사전의 값을 인쇄하는 또 다른 옵션이 있습니다. 그런 다음 ** kwargs를 사용하여 올바르게 구성되어있는 경우 가장 안쪽에있는 사전을 Q() 개체에 직접 전달하여 쿼리에 대한 키워드 인수를 만들 수 있습니다.

filters = {'name__icontains': 'Google'} 
def f(**kwargs): 
    val = kwargs.pop('name__icontains') 
    print val 

# the next two function calls print the same thing 
f(**filters) 
f(name__icontains='Google') 
: 여기
def unpack_filter(curr_filter): 
    for f in curr_filter: 
    if f == 'filters': 
     unpack_filter(curr_filter[f]) 
    elif f == 'predicate': 
     print curr_filter[f] 
    elif 'filters' in f or 'predicate' in f: 
     unpack_filter(f) 
    else: 
     print f 

키워드 인수로 사전을 전달하는 간단한 예입니다
관련 문제