2015-09-30 38 views
-1

我有一個由字符串,整數和浮點數組成的列表以及嵌套的字符串,整數和浮點數列表。這裏是一個例子Python將任意嵌套列表保存爲CSV

data = [ 
     1.0, 
     'One', 
     [1, 'Two'], 
     [1, 'Two', ['Three', 4.5]], 
     ['One', 2, [3.4, ['Five', 6]]] 
    ] 

我希望列表中的每一項寫入CSV文件中的一行。因此,鑑於以上數據,該文件是這樣的:

1.0 
One 
1,Two 
1,Two,Three,4.5 
One,2,3.4,Five,6 

有許多關於如何寫一個列表文件的資源,但我還沒有看到任何獨立這麼做的列表的嵌套。我敢肯定,我可以想出涉及很多循環的東西等等,但是沒有人有更優雅的解決方案嗎?

編輯:我想出的最好的東西是將列表中的每個項目轉換爲一個字符串,然後刪除多餘的字符(「[」,「」「等))。然後你附加的項目字符串,並將結果寫入文件:

string = '' 
for i in data: 
    line = str(i).replace("[","") 
    line = line.replace("]","") 
    line = line.replace("'","") 
    line = line.replace(" ","") 
    string+=line + '\n' 

# write string to file... 

這只是感覺kludgey,它可能是有害的,因爲它假定字符串不包含括號,引號或空格。我正在尋找更好的解決方案!

+0

請告訴我們你已經嘗試了什麼。如果你沒有,一旦你從一個方向開始,有人可以幫助你想出一個準確的解決方案。事實上,它不應該那麼辛苦 - 以寫入模式打開一個csv文件,並在循環中開始寫入文件。 – karthikr

+0

比*更優雅的解決方案*?顯示你已經嘗試過... –

+2

我認爲這是最簡單的[平坦每個項目](http://stackoverflow.com/questions/10823877/what-is-the-fastest-way-to-flatten-arbitrarily-nested -lists-in-python)然後保存到csv。 – zehnpaard

回答

3

你問什麼是或多或少都不可能。

CSV是一種扁平的表格存儲格式。 「任意嵌套列表」的層次性本質上不匹配或適合表格結構。

您絕對可以將嵌套列表弄平,以便嵌套列表的每個第一級元素都將顯示在輸出文件的一行上。但嚴格來說,這不是CSV。有些CSV閱讀器可能會正確讀取數據,但其他CSV則不會。而且,如果像你的例子那樣扁平化,你永遠無法通過閱讀文件來重建原始列表。

示範:

[1, ["Two", "Three"], 4.0] 

[1, ["Two", ["Three"]], 4.0] 

都將發出:

1 
Two,Three 
4.0 

所以在讀取文件時,讀取器/解析器不會知道原來的要返回的列表 - 第一個,第二個列表或第二個三個列表。 (我可以使這個反例任意複雜和難看。)

一般來說,嵌套/層次結構和平面/表格結構並不容易或完全兼容。

如果您想要一個任意嵌套列表的簡單存儲格式,請考慮JSONYAML。它們爲嵌套數據提供簡單,高質量的存儲。例如:

import json 

outpath = 'out.json' 
with open(outpath, "w") as f: 
    f.write(json.dumps(data)) 

會將您的數據寫入文件。要閱讀它放回:

data = json.load(open(out path)) 

但是,如果你真的想CSV上下的文字:

def flatten(l): 
    """ 
    Flatten a nested list. 
    """ 
    for i in l: 
     if isinstance(i, (list, tuple)): 
      for j in flatten(i): 
       yield j 
     else: 
      yield i 

def list2csv(l): 
    """ 
    Return CSV-ish text for a nested list. 
    """ 
    lines = [] 
    for row in l: 
     if isinstance(row, (list, tuple)): 
      lines.append(",".join(str(i) for i in flatten(row))) 
     else: 
      lines.append(str(row)) 
    return "\n".join(lines) 

print list2csv(data) 

產量:

1.0 
One 
1,Two 
1,Two,Three,4.5 
One,2,3.4,Five,6 
+0

我知道如果兩種形式不兼容。但是,就我的目的而言,嵌套列表的原始結構並不重要(實際上是任意的)。 –

+0

然後一個扁平的方法可以工作。這比使用像json這樣的現有I/O模塊更直接,它仍然不是很完善的CSV,但是可以避免大多數扁平化問題。 –

+0

好的,所以我添加了list-flatten-to-CSV代碼。這並不理想,但它會做你所問的。 –