2017-10-28 160 views
2

這是一個後續行動這樣一個問題:Python parse text file into nested dictionariesPython的遞歸函數調用的次數太多

我最初接受其建議的格式與正則表達式輸入答案,但看輸入接近後,仍有一些我不能用建議的正則表達式處理的問題。

所以我回到遞歸解析字典到行。

我至今是:

def parseToDictionary(input): 
    key = '' 
    value = '' 
    result = {} 

    if input[0].startswith('{'): # remove { 
     del input[0] 

    result.clear() # clear the dict for each recursion 

    for idx, line in enumerate(input): 
     line = line.rstrip() # remove trailing returns 

     if line.startswith('['): 
      key = line 
      value = parseToDictionary(input[idx+1:]) # parse the next level 
     elif line.startswith('}'): # reached the end of a block 
      return result 
     else: 
      elements = line.split('\t') 
      key = elements[0] 
      if len(elements) > 1: 
       value = elements[1] 
      else: 
       value = 'Not defined' # some keys may not have a value, so set a generic value here 
     if key: 
      result[key] = value 

    return result 

下面是一個例子輸入(非常簡化!):

[HEADER1] 
{ 
key1 value 
key2 long value, with a comma 
[HEADER2] 
{ 
key 1234 
emptykey 
} 
} 

輸出是:

'[HEADER2]': 
{ 
    'emptykey': 'Not defined', 
    'key': '1234' 
}, 
'key2': 'long value, with a comma', 
'key1': 'value', 
'[HEADER1]': 
{ 
    'emptykey': 'Not defined', 
    'key2': 'long value, with a comma', 
    'key1': 'value', 
    'key': '1234', 
    '[HEADER2]': 
    { 
     'emptykey': 'Not defined', 
     'key': '1234' 
    } 
}, 
'emptykey': 'Not defined', 
'key': '1234' 
} 

但應be:

'[HEADER1]': 
{ 
    'key1': 'value', 
    'key2': 'long value, with a comma', 
    '[HEADER2]': 
    { 
     'emptykey': 'Not defined', 
     'key': '1234' 
    } 
} 

因此,以[開頭的每一行都是下一個塊的關鍵字。在每個塊內部有多個鍵值對,並且還可能有另一個嵌套層。出現問題的是某些塊被多次解析,我無法弄清楚它出錯的地方。

輸入參數爲mydatafile.split('\n')

誰能幫我嗎?

+1

什麼是'input'?它是一個令牌列表嗎? –

+0

我已經添加了這個問題 – Koen

回答

2

你要跳過線,被processsed在小節:

def parse_to_dictionary(lines): 
    def parse_block(lines): 
     contents = {} 
     if next(lines).strip() != '{': 
      raise AssertionError("'{' expected") 
     for line in lines: 
      line = line.strip() 
      if line == '}': 
       return contents 
      elif line[0] == '[': 
       contents[line] = parse_block(lines) 
      else: 
       parts = line.split('\t', 1) 
       contents[parts[0]] = None if len(parts) == 1 else parts[1] 

    lines = iter(lines) 
    key = next(lines)     
    if key[0] != '[': 
     raise AssertionError("format error") 
    return {key: parse_block(lines)} 
+0

由於第一行不是'{',我將立即失敗。我真正試圖做的就是跳過'{'的路線。 – Koen

+0

所以爲了解決這個問題,我提出了'raise AssertionError(''''expected')'行並縮進了for循環。現在完美工作。 – Koen

+0

無視這些評論,我的輸入文件中出現錯誤。 – Koen