2015-08-31 73 views
1

我的工作分配在Python類目前列出的元組,以及一個特定部分要求我在「文本的格式導入CSV文件(數據,數字,數字,...,數字,數字「),並且以這種格式返回數據作爲元組列表:解析CSV不使用CSV模塊

[(’Text’, [number, number, ..., number, number]), 
(’Text’, [number, number, ..., number, number]), 
.....] 
[(’Text’, [number, number, ..., number, number]), 
(’Text’, [number, number, ..., number, number]), 
.....] 

我想我得打開文件,並開始由線正確路線讀它(見下面代碼段)的實際過程,但我不能就如何處理方面着手每行解析成格式相當肯定需要。

def load_data(filename): 
    open(filename) 
    for line in filename 

我試圖尋找幫助,但唯一的幫助,我似乎找到說只使用CSV模塊(這是不是特別有幫助,因爲我們不允許任何導入模塊吧數學庫)或者以不同格式輸入和/或輸出數據。如果任何人都可以給我一些關於我應該做什麼的指示,或者我可以在哪裏開始,這將是超級有用的。謝謝!

編輯:每通過@dotancohen這裏提出的建議是一些示例數據:

Slow Loris, 21.72, 29.3, 20.08, 29.98, 29.85, 26.22, 29.68 
Ocelot, 57.51, 47.59, 55.89, 47.15, 46.71, 51.7, 46.68, 54.54 
Tiger, 75.0, 82.43, 112.11, 89.93, 103.19, 80.6, 113.44, 75.55, 102.29, 108.1, 98.84, 101.48, 77.75, 98.57, 70.31, 78.28, 80.18 

而且下面是我目前所面對的是一個潛在的解決方案:

def load_data(filename): 
    open(filename) as file 
    output = [] 
    for line in filename 
     temp_list = line.split(',') 
     temp_item = temp_list.pop(0) 
     tup = (temp_item, temp_list) 
     output.append(tup) 
    return output 

回答

2

CSV文件通常有逗號或製表符分隔的線,所以在天真情況下,這會給你不同的領域:

for line in filename: 
    fields = line.split(',') # For comma-delimited files 
    # - or - 
    fields = line.split('\t') # For tab-delimited files 

然而,我們很少能夠讓自己成爲很天真。 CSV文件中,除其他外,要注意以下幾點:

  1. 引用的值:這是一個CSV法律領域:「我思故我在」。你需要小心,不要在引號內的逗號分割。 Newines也可以出現在引用的值中,所以你不能可靠地使用for line in filename
  2. 轉義引號引用中值:這是一個CSV法律領域:「她說:\」我也這麼認爲\「」。這意味着你的狀態機匹配每個字符的引號外引號的狀態也需要一個回顧機制。

因此,爲了可靠地解析CSV文件,您需要一個能夠跨文件保存狀態的狀態機。一路上有可怕的驚喜,比如在Python 2中處理Unicode CSV文件(提示:如果你有非ASCII文本,請使用Python 3)。還有一些小驚喜,如某些應用程序在逗號分隔符之後放置空格,或者不在行尾添加空白字段的逗號。

因此,如果您要將接受來自用戶的CSV輸入文件,請使用CSV模塊。然而,如果能控制輸入(即,從其他腳本產生它),那麼就可以使用幼稚line.split('\t')方法。

根據OP公佈的樣本數據,我們看到他不必擔心引用字段,但他的CSV源實際上在逗號分隔符之後添加了錯誤的空格。因此,這是具體到OP的情況代碼:

for line in filename: 
    fields = line.split(',') 
    fields = [x.strip() for x in fields] # Remove whitespace 
+0

對,所以我會使用line.split(','),因爲我的文件完全是用逗號分隔的。儘管我無法控制輸入,但我們已經獲得了兩個CSV文件,程序將針對這兩個文件進行測試,並且它們都具有相同的一致格式,而且沒有引號值,轉義引號或非Unicode字符(儘管我們正在使用Python 3)。我應該將文本分割成單獨的變量,然後將文本作爲元組重新加入數字中?這應該給我所尋找的輸出,對不對? – RandosaurusRex

+0

@RandosaurusRex - 這看起來是一段很好的工作方法。你可能沒有進一步的幫助就可以完成它,但如果你嘗試這種設計,並且麻煩回來並要求詳細的幫助。我懷疑你會從這裏得到好處,但如果你確實遇到了從這裏到最後的跳閘點,那麼不會感到羞恥。 – jwpfox

+0

@RandosaurusRex:我希望在給出yes或no之前查看示例文件,能否請您在問題中添加幾行示例行?謝謝。 – dotancohen

1

的一個關鍵概念看看會是split()

根據逗號拆分CSV似乎是拼圖的重要組成部分,你不同意。

+0

所以我要使用的東西沿着line.split的線條來替換這一行lst = zip(x,y)( '') ?如果我這樣做,我應該做一些事情,如將列表分成兩個子列表,一個與文本和另一個與數字,然後以某種方式將它們鏈接爲單個列表項目? – RandosaurusRex

0

這是CSV文件data

text1 1 2 3 4 5 
text2 6 7 8 9 10 
text3 11 12 13 14 15 

您可以使用setdefaultzip實現了輸出你Python2需要

d = {} 
with open('your_file.csv', 'rb') as f: 
    for line in f: 
     line = line.split() 
     for i in line[1:]: 
      key = (line[0]) 
      d.setdefault(key, []).append(int(i)) 

x = sorted(d.keys()) 
y = sorted(d.values()) 
lst = zip(x,y) 
print (lst) 

輸出:

[('text1', [1, 2, 3, 4, 5]), ('text2', [6, 7, 8, 9, 10]), ('text3', [11, 12, 13, 14, 15])] 

Python3你有lst = list(zip(x,y))