python csv writer如果行键不存在

时间:2016-08-02 14:58:10

标签: python

以下脚本错误输出:

import csv,time,string,os,requests, datetime

test = "\\\\network\\Shared\\test.csv"

fields = ["id", "Expiration Date", "Cost", "Resale" ]

with open(test) as infile, open("c:\\upload\\tested.csv", "wb") as outfile:
    r = csv.DictReader(infile)
    w = csv.DictWriter(outfile, fields, extrasaction="ignore")
    r = (dict((k, v.strip()) for k, v in row.items() if v) for row in r)

    wtr = csv.writer( outfile )                                                                                                                                                                                                                                                                                                                                         
    wtr.writerow(["id", "upload_date", "cost", "resale"])
    for i, row in enumerate(r, start=1):
        row['id'] = i
        print(row['Expiration Date']
        row['Expiration Date'] = datetime.datetime.strptime(row['Expiration Date'][:10], "%m/%d/%Y").strftime("%Y-%m-%d")
        w.writerow(row)


D:\Python\Scripts>python test.py
Traceback (most recent call last):
  File "test.py", line 18, in <module>
    print(row['Expiration Date'])
KeyError: 'Expiration Date'

所以我想我明白发生了什么 - 从原始文件中得到这样的东西:

Expiration Date     Cost     Resale
2016-01-01          1.00     2.00
                    1.42     2.42
2016-05-02          1.45     9.00

从我可以收集的内容中,有一行未填充到期日期列。如何强制DictWriter跳过空白 - 假设这是我错误的原因?

2 个答案:

答案 0 :(得分:1)

实际上,dict生成的csv.DictReader只会将None放入未找到的字段中,因此您不应该收到该错误。您没有使用DictReader的功能来生成正确的dict!据我所知,您尝试使用行r = (dict((k, v.strip()) for k, v in row.items() if v) for row in r)自行解析。但这实际上并不奏效。如果您之后打印行,则会得到:

{'Expiration Date     Cost     Resale': '2016-01-01          1.00     2.00'}
{'Expiration Date     Cost     Resale': '1.42     2.42'}
{'Expiration Date     Cost     Resale': '2016-05-02          1.45     9.00'}

所以每个dict只包含一个键。您的文件存在的问题是,您在行之间没有有效的分隔符。看起来你的意思是使用空格,但你在Expiration Date中也有一个空格。你将不得不摆脱它。如果你这样做,那么你可以像这样使用DictReader

import csv,time,string,os,requests, datetime

test = "test.csv"

with open(test) as infile:
    r = csv.DictReader(infile, delimiter=" ", skipinitialspace=True)
for row in r:
    print(row)

现在会给你:

{'Resale': '2.00', 'Cost': '1.00', 'ExpirationDate': '2016-01-01'}
{'Resale': None, 'Cost': '2.42', 'ExpirationDate': '1.42'}
{'Resale': '9.00', 'Cost': '1.45', 'ExpirationDate': '2016-05-02'}

这是一个合适的dict(请注意,读者无法说明,第一个元素是缺少的元素)。现在,您只需排除编写不完整的行。一个很好的方法是here

import csv,time,string,os,requests, datetime

test = "test.csv"

with open(test) as infile:
    r = csv.DictReader(infile, delimiter=" ", skipinitialspace=True)

    for row in r:
        if not any(val in (None, "") for val in row.itervalues()):
            print(row)

最后,这将为您提供dict的所有有效行:

{'Resale': '2.00', 'Cost': '1.00', 'ExpirationDate': '2016-01-01'}
{'Resale': '9.00', 'Cost': '1.45', 'ExpirationDate': '2016-05-02'}

答案 1 :(得分:0)

你有一个KeyError访问不在x['Expiration Date']的dict中的内容,所以你可以说x.get('Expiration Date')或可能'Expiration Date' in x来发现它是否存在并有条件地丢弃该行。