[英]Tab Formatted Nested String to Nested List ~ Python
大家好 ,在設法通過使用Beautiful Soup抓取來獲取一些數據之后……我想格式化該數據,以便可以輕松地將其導出為CSV和JSON。
我的問題是,如何翻譯此內容 :
Heading :
Subheading :
AnotherHeading :
AnotherSubheading :
Somedata
Heading :
Subheading :
AnotherHeading :
AnotherSubheading :
Somedata
變成這個 :
[
['Heading',['Subheading']],
['AnotherHeading',['AnotherSubheading',['Somedata']]],
['Heading',['Subheading']],
['AnotherHeading',['AnotherSubheading',['Somedata']]]
]
為了清楚起見縮進
熱烈的感謝,感謝您對任何救援嘗試的感謝 !
到目前為止,我們得到了幫助:
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']]
]
這是一個副本: https : //repl.it/yvM/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)
首先,您要清除不必要的空格,因此您要列出所有包含空格以外的行,並設置主循環的所有默認值。
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%無法正常工作,我認為這是因為我沒有安裝Python 3,所以一直在使用repl.it。 它在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
就像是:
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.