2009-07-29 60 views
3

我試圖從CSV文件中提取一堆行並將它們寫入另一個行,但我遇到了一些問題。Python CSV DictReader/Writer問題

import csv 

f = open("my_csv_file.csv", "r") 
r = csv.DictReader(f, delimiter=',') 
fieldnames = r.fieldnames 

target = open("united.csv", 'w') 
w = csv.DictWriter(united, fieldnames=fieldnames) 

while True: 
try: 
    row = r.next() 
    if r.line_num <= 2: #first two rows don't matter 
     continue 
    else: 
     w.writerow(row) 

except StopIteration: 
    break 

f.close() 
target.close() 

運行此,我得到以下錯誤:

Traceback (most recent call last): 
File "unify.py", line 16, in <module> 
    w.writerow(row) 
File "C:\Program Files\Python25\lib\csv.py", line 12 
    return self.writer.writerow(self._dict_to_list(row 
File "C:\Program Files\Python25\lib\csv.py", line 12 
    if k not in self.fieldnames: 
TypeError: argument of type 'NoneType' is not iterable 

不能完全確定什麼,我錯了洞。

回答

13

我也不知道,但因爲你所做的只是從一個文件複製行到另一個爲什麼你打擾csv的東西呢?爲什麼不一樣的東西:

f = open("my_csv_file.csv", "r") 
target = open("united.csv", 'w') 

f.readline() 
f.readline() 
for line in f: 
    target.write(line) 
+0

輝煌記錄。我確實傾向於過分複雜的東西。謝謝。 – saturdayplace 2009-07-29 20:37:56

+0

這個答案很精彩,因爲它解決了潛在的問題;) – Jaykul 2013-02-19 23:19:35

1

至於例外,看起來像這樣一行:

w = csv.DictWriter(united, fieldnames=fieldnames) 

應該

w = csv.DictWriter(target, fieldnames=fieldnames) 
1

你得到錯誤的原因是最有可能您的原始CSV文件(my_csv_file.csv)沒有標題行。因此,當您構建reader對象時,其fieldnames字段被設置爲None

當您嘗試使用編寫器編寫一行時,它首先檢查以確保dict中沒有鍵不在其已知字段的列表中。由於fieldnames設置爲None,因此嘗試解除引用密鑰名稱時會引發異常。

13

要清除有關錯誤的疑惑:你得到它,因爲r.fieldnames只有在您首次使用r從輸入文件中讀取後纔會設置。因此,你寫它的方式,fieldnames將始終被初始化爲None

只有在您閱讀r的第一行之後,您纔可以初始化w = csv.DictWriter(united, fieldnames=fieldnames),這意味着您將不得不重構您的代碼。

這種行爲在Python Standard Library documentation

DictReader objects have the following public attribute:

csvreader.fieldnames

If not passed as a parameter when creating the object, this attribute is initialized upon first access or when the first record is read from the file.