2013-07-16 101 views
1

我有一個包含字段名稱的電子表格:添加到現有的電子表格?

['name','occupation','company','address','address_2','city','state','zip','phone' '電子郵件','網站','描述']

並希望在此電子表格中添加其他包含較少字段名的數據電子表格(儘管所有其他字段名都包含在此電子表格中) 。

我得到一個奇怪的錯誤:

Samuel-Finegolds-MacBook-Pro:~ samuelfinegold$ /var/folders/jv/9_sy0bn10mbdft1bk9t14qz40000gn/T/Cleanup\ At\ Startup/merge-395698810.980.py.command ; exit; 
['name', 'occupation', 'company', 'address', 'address_2', 'city', 'state', 'zip', 'phone,fax', 'email', 'website', 'description'] 
Traceback (most recent call last): 
    File "/Users/samuelfinegold/Documents/noodle/merge.py", line 14, in <module> 
    gc_all_dict.writerow(row) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 148, in writerow 
    return self.writer.writerow(self._dict_to_list(rowdict)) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 144, in _dict_to_list 
    ", ".join(wrong_fields)) 
TypeError: sequence item 0: expected string, NoneType found 
logout 

[Process completed] 

當我運行以下命令:

import csv 

# compile master spreadsheet 
with(open('gc_all.txt','w')) as gc_all: 

    fieldnames = ['name', 'occupation', 'company', 'address', 'address_2','city', 'state', 'zip', 'phone,' 'fax', 'email', 'website', 'description'] 
    gc_all_dict = csv.DictWriter(gc_all, fieldnames = fieldnames, delimiter = '\t') 
    print gc_all_dict.fieldnames 

    with(open('/Users/samuelfinegold/Documents/noodle/aicep/aicep_scrape_output.txt', 'rU')) as aicep: 
     aicep_dict = csv.DictReader(aicep, fieldnames = fieldnames, delimiter = '\t') 
     for row in aicep_dict: 
#    print row 
      gc_all_dict.writerow(row) 


    for row in gc_all: 
     print row 

假數據:

name occupation company address address_2 city state zip phone fax email website description 
Rob Er  Step Up 123 Road Dr  New York NY 10011 1234567891 1234567891 [email protected] www.stepUp.com A great counselor 
Bob B. Bob  For Your Rights 12 2nd Ave  San Francisco CA 94109 1234567891 1234567891 [email protected]  
Snob Job  Marley Inc. 12 1st Ave  Denver CO 80231 1234567891 1234567891 [email protected]  What a counselor! 
+0

你可以給我們一個小樣本aicep_scrape_output.txt文件,以便我們可以調試嗎? – abarnert

+1

有人可能已經問過這個問題,但是有沒有理由不使用像[pandas](http://pandas.pydata.org)這樣的更高級別的庫? – DSM

+0

@DSM:一般來說問題不錯......但如果他所做的只是將異構CSV連接到Excel中使用的超集CSV中,pandas將不會添加任何有用的東西(除非出現雙倍意外時可能會出現更好的錯誤消息發生…)。 – abarnert

回答

2

這裏真正的問題是,儘管你在你的問題中聲稱,所有其他人的域名是而不是包括在這個電子表格中。

您可以通過查看所提出的那條線上的線來判斷。 DictWriter._dict_to_list看起來是這樣的:

def _dict_to_list(self, rowdict): 
    if self.extrasaction == "raise": 
     wrong_fields = [k for k in rowdict if k not in self.fieldnames] 
     if wrong_fields: 
      raise ValueError("dict contains fields not in fieldnames: " + 
          ", ".join(wrong_fields)) 
    return [rowdict.get(key, self.restval) for key in self.fieldnames] 

所以,它找到了一個場,是不是在你的DictWriter


但是爲什麼它會在嘗試創建錯誤時引發奇怪的錯誤?因爲缺少的字段被命名爲NoneDictWriter代碼不是用來處理這個問題的。所以,這是問題#2。


爲什麼字段名爲None?因爲這是DictReader每當它找到一個不適合您提供的fieldnames的列時產生的結果。你可以通過print row看到這個:dict的其中一個元素將會是None: 'foo'。所以,這是問題#3。


那麼你如何解決這個問題呢?

那麼,顯而易見的事情就是讓你的聲明成真:使目標中的字段成爲源代碼中字段的嚴格超集。

或者,您可以告訴您的DictReader跳過額外的字段,或者您的DictWriter忽略它們而不是提高。例如,只需將extrasaction='ignore'添加到您的DictWriter構造函數中,問題就會消失。

但是,真的,你不應該那樣做。 raise在這裏遇到了一個合法的bug;它只是沒有這樣做的一個非常有用的錯誤信息。

+1

我印象深刻。而且,即使代碼成功,gc_all:行中的下一行也肯定會失敗。 –

+0

@TimPietzcker:好點。另外,考慮到他顯然希望將一堆CSV文件連接在一起,使用'w'而不是'a'或'w +'可能是一個壞主意... – abarnert

+0

「他」會將模式更改爲w + – goldisfine

相關問題