【发布时间】:2025-12-16 18:00:01
【问题描述】:
这个脚本的目的是获取一个传入的 csv 文件,用 DictReader 读取它, 获取读取的键,查看它们是否匹配 fieldMap 字典中的任何预先指定的值,如果匹配,则将这些键附加到我的 hdrlist。然后,将头列表写入输出文件调用ofp。
我遇到的这个问题是,当我没有与 fieldMap 中预先指定的值之一匹配的键时,我需要插入一个空白('')。
我已经尝试在 else 语句中将空白值附加到 hdrlist 并在我的 fieldMap 字典中有一个空白键值对:
if row.has_key(ft_test):
hdrlist.append(ft_test)
else:
hdrlist.append('')
'':[''] #blank key:value pair
,然后是我的:
if hdrlen != len(hdrlist)-1:
print "Cannot Cannot find a key for %s in file %s" % (ft,fn)"
错误处理语句返回的打印语句比我认为的要多,我不确定为什么。
如果有人能阐明如何在我的 ofp.write(fmtstring) 中插入空白,将不胜感激。
另外,如果有人能解释为什么我得到的打印语句比我认为我应该使用上述 else 语句得到更多的打印语句,我将不胜感激。
我的整个脚本如下,如果需要任何其他信息来帮助我编写此代码,我会很乐意提供。
这里是一个输入文件的示例,它会产生许多打印语句。
input_file.csv = {'cust_no':1, 'streetaddr':'2103 Union Ave','address2':' ','city':'Chicago'}
#!/usr/bin/env python
import sys, csv, glob
fieldMap = {'zipcode':['Zip5', 'zip9','zipcode','ZIP','zip_code','zip','ZIPCODE'],
'firstname':['firstname','FIRSTNAME'],
'lastname':['lastname','LASTNAME'],
'cust_no':['cust_no','CUST_NO'],
'user_name':['user_name','USER_NAME'],
'status':['status','STATUS'],
'cancel_date':['cancel_date','CANCEL_DATE'],
'reject_date':['REJECT_DATE','reject_date'],
'streetaddr':['streetaddr','STREETADDR','ADDRESS','address'],
'streetno':['streetno','STREETNO'],
'streetnm':['streetnm','STREETNM'],
'suffix':['suffix','SUFFIX'], #suffix of street name: dr, ave, st
'city':['city','CITY'],
'state':['state','STATE'],
'phone_home':['phone_home','PHONE_HOME'],
'email':['email','EMAIL'],
'':['']
}
def readFile(fn,ofp):
count = 0
CSVreader = csv.DictReader(open(fn,'rb'), dialect='excel', delimiter=',')
for row in CSVreader:
count+= 1
if count == 1:
hdrlist = []
for ft in fieldMap.keys():
hdrlen = len(hdrlist)
for ft_test in fieldMap[ft]:
if row.has_key(ft_test):
hdrlist.append(ft_test)
if hdrlen != len(hdrlist)-1:
print "Cannot find a key for %s in file %s" % (ft,fn)
if len(hdrlist) != 16:
print "Another error. Not all header's have been assigned new values."
if count < 5:
x=len(hdrlist)
fmtstring = "%s\t" * len(hdrlist) % tuple(row[x] for x in hdrlist)
ofp.write(fmtstring)
break
if __name__ == '__main__':
filenames = glob.glob(sys.argv[1])
ofp = sys.stdout
ofp.write("zipcode\tfirstname\tlastname\tcust_no\tuser_name\tstatus\t"
"cancel_date\treject_date\tstreetaddr\tstreetno\tstreetnm\t"
"suffix\tcity\tstate\tphone_home\temail")
for filename in filenames:
readFile(filename,ofp)
样本数据:
cust_no,status,streetaddr,address2,city,state,zipcode,billaddr,servaddr,title,latitude,longitude,custsize,telemarket,dirmail,nocredhold,email,phone_home,phone_work,phone_fax,phone_page,phone_cell,phone_othr,taxrate1,taxrate2,taxrate3,taxtot,company,firstname,lastname,user_name,dpbc,container,seq,paytype_am,paytype_di,paytype_mc,paytype_vi
0,0,'123 fake st.',,'chicago','il',60185,'123 billaddr st.','123 servaddr st.','mr.',43.123,54.234 ,2000,'TRUE','TRUE','TRUE','email@email.com',(666)555-6666,,,,,,,,,,,'bob','smith','bob smith',,,,'TRUE','TRUE','TRUE','TRUE'
0,0,'123 fake st.','','chicago','il',60185,'123 billaddr st.','123 servaddr st.','mr.',43.123,54.234 ,2000,'TRUE','TRUE','TRUE','email@email.com',(666)555-6666,'','','','','','','','','','','bob','smith','bob smith','','','','TRUE','TRUE','TRUE','TRUE'
【问题讨论】:
-
您能否提供至少一个产生过多打印语句的输入文件?
-
您添加的内容与您的
for row in CSVreader:循环中的row的值类似。我的意思是文件中的一行或多行实际数据。您可以稍微更改一下以保护隐私。还包括在 csv 文件中定义字段名称的第一行会很有用。 -
很难让它像表格一样格式化,但我的列标题是:邮政编码,名字,姓氏,cust_no,用户名,状态,cancel_date,reject_date,streetaddr,streetno,streetnm,后缀,城市,状态,电话家庭,电子邮件。在每个列标题下方是多行适当类型的数据。
-
你不能从 csv 文件中复制一两个问题行并将它们粘贴到你的问题中吗?我想要一些真实的数据来测试。顺便说一句,列标题决定了
csv.DictReader可能在每行字典中返回的键,因此对每一行执行所有冗余检查似乎效率低下(且复杂)。 -
如果我复制所有行,则无法将其格式化为表格,但我复制了 5 列,其中包含虚假数据。
标签: python if-statement dictionary