2015-07-21 85 views
1

你好人,管理與美麗的湯颳得到一些數據... 後,我想這樣我可以很容易地將其導出爲CSV和JSON格式的數據。選項卡格式化字符串嵌套到嵌套列表〜Python的

問題這裏是一個如何翻譯這個

Heading : 
    Subheading : 

AnotherHeading : 
    AnotherSubheading : 
     Somedata 

Heading : 
    Subheading : 

AnotherHeading : 
    AnotherSubheading : 
     Somedata 

進入這個

[ 
['Heading',['Subheading']], 
['AnotherHeading',['AnotherSubheading',['Somedata']]], 
['Heading',['Subheading']], 
['AnotherHeading',['AnotherSubheading',['Somedata']]] 
] 

齒痕爲清楚起見

任何RESC如果您有任何疑問,請致電謝謝

因此,與幫助到目前爲止,我們得到:

def parse(data): 
    stack = [[]] 
    levels = [0] 
    current = stack[0] 
    for line in data.splitlines(): 
    indent = len(line)-len(line.lstrip()) 
    if indent > levels[-1]: 
     levels.append(indent) 
     stack.append([]) 
     current.append(stack[-1]) 
     current = stack[-1] 
    elif indent < levels[-1]: 
     stack.pop() 
     current = stack[-1] 
     levels.pop() 
    current.append(line.strip().rstrip(':')) 
    return stack 

與代碼的問題是,它返回......

[ 
'Heading ', 
['Subheading '], 
'AnotherHeading ', 
['AnotherSubheading ', ['Somedata'], 'Heading ', 'Subheading '], 'AnotherHeading ', 
['AnotherSubheading ', ['Somedata']] 
] 

這裏是一個REPL: https://repl.it/yvM/1

+0

他們是否縮進用空格或製表符? ('\ t')它們是否始終只是其中的一個? – SuperBiasedMan

+0

我添加了一個repl! https://repl.it/yvM/1 –

+0

嵌套有多深?超越3級? – SuperBiasedMan

回答

0

那麼首先你要清除不必要的空白,所以你要列出所有包含比空白更多東西的行,並設置你從主循環開始的所有默認值。

teststring = [line for line in teststring.split('\n') if line.strip()] 
currentTab = 0 
currentList = [] 
result = [currentList] 

這種方法回覆在列表上的可變性,所以設置currentList爲空列表,然後設置result[currentList]是重要的一步,因爲我們現在可以追加到currentList

for line in teststring: 
    i, tabCount = 0, 0 

    while line[i] == ' ': 
     tabCount += 1 
     i += 1 
    tabCount /= 8 

這是我能想到的在每行開頭檢查製表符的最佳方式。另外,是的,你會注意到我確實檢查了空格,而不是標籤。標籤只有100%沒有工作,我認爲這是因爲我使用repl.it,因爲我沒有安裝Python 3。它在Python 2.7上工作得很好,但我不會把我沒有驗證過的代碼放到工作中。如果您確認使用\t和刪除tabCount /= 8可以產生所需的結果,我可以編輯此內容。

現在,檢查如何縮進行。如果它與我們的currentTab值相同,那麼只需追加到currentList即可。

if tabCount == currentTab: 
     currentList.append(line.strip()) 

如果它更高,這意味着我們已經進入更深的列表級別。我們需要一個嵌套在currentList中的新列表。

elif tabCount > currentTab: 
     newList = [line.strip()] 
     currentList.append(newList) 
     currentList = newList 

倒退是棘手,因爲數據只包含3個嵌套級別我選擇硬編碼如何處理值0和1(2應該總是導致上述塊中的一個)做。如果沒有標籤,我們可以在result附加一個新列表。

elif tabCount == 0: 
     currentList = [line.strip()] 
     result.append(currentList) 

這主要是爲一個標籤深航向一樣,除了你應該追加到result[-1],因爲這是最後的主標題嵌套進。

elif tabCount == 1: 
     currentList = [line.strip()] 
     result[-1].append(currentList) 

最後,確保currentTab更新一下我們目前的tabCount是那麼下一次迭代的行爲正確。

currentTab = tabCount 
+0

感謝你生病了看看馬上 –

+0

你可以給我的repl請,我似乎無法將這件事 –

+0

這是放在一起[這裏](http://repl.it/ zFs),請確保你檢查了你的Python3上的空白區域測試,因爲我不確定當它不在repl上時它將如何工作。 – SuperBiasedMan

-2

例如:

def parse(data): 
    stack = [[]] 
    levels = [0] 
    current = stack[0] 
    for line in data.splitlines(): 
     indent = len(line)-len(line.lstrip()) 
     if indent > levels[-1]: 
      levels.append(indent) 
      stack.append([]) 
      current.append(stack[-1]) 
      current = stack[-1] 
     elif indent < levels[-1]: 
      stack.pop() 
      current = stack[-1] 
      levels.pop() 
     current.append(line.strip().rstrip(':')) 
    return stack[0] 

雖然你的格式看起來很像YAML;你可能想看看PyYAML。

+0

爲什麼downvote? – refi64

+0

工作得很好!做得好! –

+0

@ user2924944如果你喜歡我的回答,你可以點擊綠色的勾號來接受它。 :) – refi64

1

謝謝兩位kirbyfan64sos和SuperBiasedMan

def parse(data): 

    currentTab = 0 
    currentList = [] 
    result = [currentList] 

    i = 0 
    tabCount = 0 

    for line in data.splitlines(): 

    tabCount = len(line)-len(line.lstrip()) 

    line = line.strip().rstrip(' :') 

    if tabCount == currentTab: 
     currentList.append(line) 

    elif tabCount > currentTab: 
     newList = [line] 
     currentList.append(newList) 
     currentList = newList 

    elif tabCount == 0: 
     currentList = [line] 
     result.append(currentList) 

    elif tabCount == 1: 
     currentList = [line] 
     result[-1].append(currentList) 

    currentTab = tabCount 

    tabCount = tabCount + 1 
    i = i + 1 

    print(result)