2012-05-04 20 views
0

我有一個未知的號碼的,看起來或多或少像這樣(設置寬度不同的長度)結合的未知長度但具有相同寬度的CSV文件列在Python

Header1, Header2, Header3, Header4 
1,2,3,4 
11,22,33,44 
1,2,3,4 

輸出看起來像這樣輸入的CSV文件。

Header1,Header3, ,Header1,Header3, ,... 
1,3, ,1,3, ,... 
... 

目前我可以讀取所有的輸入文件轉換成字符串,我知道如何讀取每個文件的第一行,並在需要的格式打印出來,但我堅持就如何使一個循環去每個文件的下一行並打印該數據。由於這些文件的長度不同,所以我不知道如何處理這些文件,並將它們放在空格中作爲佔位符來保存格式。以下是我的代碼。

csvs = [] 
hold = [] 
i=0   # was i=-1 to start, improved 
for files in names: 
    i=i+1 
    csvs.append([i]) 
    hold.append([i]) 

#z=0 
for z in range(i): 
    # putting csv files into strings 
    csvs[z] = csv.reader(open(names[z],'rb'), delimiter=',') 

line = []  
#z=0 
for z in range(i): 
    hold[z]=csvs[z].next() 
    line = line + [hold[z][0], hold[z][3], ' '] 

print line 
writefile.writerow(line) 

names是保存csv文件路徑的字符串。此外,我對這件事還是比較陌生的,所以如果你看到一些我可以做得更好的地方,我就會全神貫注。

+0

對於範圍(i)中的z,'z = 0'是不必要的:' –

+0

謝謝,我已經對其進行了修改。同樣由於你的評論我已經改善了我的價值。我將編輯代碼以反映您的建議。 – deadstump

+0

您是否知道用於讀取逗號分隔數據的Python的'csv'模塊? –

回答

3

假設您知道如何在某些文件比其他文件長時合併行。這是一種使線條和文件迭代更容易的方法。

from itertools import izip_longest 
# http://docs.python.org/library/itertools.html#itertools.izip_longest 

# get a list of open readers using a list comprehension 
readers = [csv.reader(open(fname, "r")) for fname in list_of_filenames] 

# open writer 
output_csv = csv.writer(...) 

for bunch_of_lines in izip_longest(*readers, fillvalue=['', '', '', '']): 
    # Here bunch_of_lines is a tuple of lines read from each reader, 
    # e.g. all first lines, all second lines, etc 
    # When one file is past EOF but others aren't, you get fillvalue for its line. 
    merged_row = [] 
    for line in bunch_of_lines: 
     # if it's a real line, you have 4 items of data. 
     # if the file is past EOF, the line is fillvalue from above 
     # which again is guaranteed to have 4 items of data, all empty strings. 
     merged_row.extend([line[1], line[3]]) # put columns 1 and 3 
    output_csv.writerow(merged_row) 

此代碼僅在最長的文件結束後停止,並且循環只有5行代碼。 我想你會自己頭像。

備註:在Python中,在瞭解for循環和列表解析的工作方式後,您需要使用range()和整數索引訪問列表。在Python中,forforeach是其他語言;它與指數無關。

+0

+1用於使用izip_longest()來簡化解決方案。 –

+0

這工作得很好!我非常接近讓這個程序按照我想要的方式工作!謝謝!我會投票給你,但我還沒有被允許。謝謝! – deadstump

1

這不會給備用逗號你在你的輸出表現,但不會是很難通過只彈出一個額外的空白字段插入數據我們每次追加到它的時候補充:

import csv 

names=['test1.csv','test2.csv'] 
csvs = [] 
done = [] 
for name in names: 
    csvs.append(csv.reader(open(name, 'rb'))) 
    done.append(False) 

while not all(done): 
    data = [] 
    for i, c in enumerate(csvs): 
     if not done[i]: 
      try: 
       row = c.next() 
      except StopIteration: 
       done[i] = True 
     if done[i]: 
      data.append('') 
      data.append('') 
      # data.append('') <-- here 
     else: 
      data.append(row[0]) 
      data.append(row[3]) 
      # data.append('') <-- and here for extra commas 
    if not all(done): 
     print ','.join(data) 

另外,我沒有明確地關閉任何東西,如果這是長時間運行的過程的一部分,你應該這樣做。

+0

如果你想寫一個CSV文件,使用'csv.writer'來處理逗號和其他東西是明智的;已經導入模塊'csv'來讀取輸入的CSV。 – 9000

相關問題