我有一个包含字段名的电子表格:
['name','Occup','company','address','address_2','city','state','zip','phone','fax','email','website ','description']
并希望在此电子表格中添加包含较少字段名的其他数据电子表格(尽管所有其他字段名称都包含在此电子表格中)。
我收到了一个奇怪的错误:
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 a@b.com www.stepUp.com A great counselor
Bob B. Bob For Your Rights 12 2nd Ave San Francisco CA 94109 1234567891 1234567891 c@d.com
Snob Job Marley Inc. 12 1st Ave Denver CO 80231 1234567891 1234567891 g@h.com What a counselor!
答案 0 :(得分: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
。
但是为什么在尝试创建错误时会引发奇怪的错误?因为缺少的字段名为None
。 DictWriter
代码不是为了处理它而构建的。那就是问题#2。
为什么名为None
的字段?因为只有当DictReader
找到不符合您提供的fieldnames
的列时,才会生成print row
。您可以通过dict
看到此信息:None: 'foo'
的其中一个元素将类似于DictReader
。那么,这就是问题#3。
那你怎么解决这个问题?
嗯,显而易见的事情是让你的声明成立:让目标中的字段成为源中字段的严格超集。
或者,您可以告诉DictWriter
跳过额外字段,或者extrasaction='ignore'
忽略它们而不是提高字段。例如,只需将DictWriter
添加到raise
构造函数中,问题就会消失。
但实际上,你不应该这样做。 {{1}}在这里抓到了一个合法的错误;它只是没有使用非常有用的错误消息。