2016-07-14 238 views
1

我對Python相當陌生,我試圖將過濾器查詢建立爲帶有n深度字典的最終結果。裏面可以有其他字典和列表。如何遍歷一個深度嵌套的字典,其中包含Python中的列表和其他字典?

這是我的結構:

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']} 
      ] 
     } 
    ] 
} 

我希望這將轉化爲A +符合Q對象(B或C)+(d或E)!

然而,我的第一個問題是,如何遍歷每個鍵值對的字典?

這是我迄今爲止的內容,但您可以在列表中找到限制,因爲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語句來決定如何響應。 上面的答案將打印最內層的字典的鍵和值,這可能是你想要的。 這是另一個選項,只有在「過濾器」或「謂詞」不是關鍵字時纔會打印字典的值。然後,您可以使用** kwargs並將正確構造的最內部字典直接傳遞給Q()對象以爲查詢創建關鍵字參數。

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 

下面是一個簡單的例子傳入一個字典作爲關鍵字參數:

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')